3

我有一个与此等效的 Visual Studio 2012 项目:

头文件.h

template< class T >
inline int Demonstrate( const char *txt, T *input )
{
  return printf("%s %d %f\n", txt, input->Integer(), input->Real() );
}

源.cpp

#include "Header.h"

class Foo 
{
public:
   int Integer() { return 2; }
   float Real() { return 3.14159f; }
};

int main()
{
   Foo example;
   printf( "%d\n", Demonstrate( "foo:", &example ) );
   return 0;
}

然而,当我编译时收到 LNK2019 错误:

unresolved external symbol "int __cdecl Demonstrate(char const *,class Foo *)"

通常,当模板化函数在标头中声明但仅在 cpp 中定义时,会发生这种情况,但这里不是这种情况。该函数在标题中内联定义。

什么可能导致这种情况,我该如何解决?

编辑

即使我完全删除标题并将 Demonstrate() 粘贴在 Source.cpp 的顶部,也会发生这种情况。项目属性中的“内联函数扩展”是否设置为“默认”或"/Ob2". 这一定是一些项目设置的事情,但是什么?

4

2 回答 2

2

所以我追踪了这个,结果发现乔尔走在了正确的道路上。函数 Demonstrate() 已经在多个头文件中多次原型化——以一种非常不明显的方式。有明确的int Demonstrate( const char *txt, Foo *input )声明,这是我用模板替换的。

但是还有其他几个头文件散布在其中,与此类似(您可以推断出实际的函数和类名称要复杂得多):

header a.h:

#define FUNC_PREFIX Demo

header b.h:

#define REGISTER_CLASS( retype, classname, FUNC_SUFFIX ) retype FUNC_PREFIX ## FUNC_SUFFIX ( const char *txt, classname *ptr )

header c.h:

REGISTER_CLASS( int, Foo, nstrate );
REGISTER_CLASS( int, Bar, nstrate );
// etc

我不知道可以从中得出什么结论。一方面,对于一个非常具体的代码库来说,这是一个非常具体的错误,而且过于本地化而不能成为一个有用的 SO 问题。另一方面,这里有一个可教的时刻:

不要使用宏以偷偷摸摸的方式定义全局函数

否则像我这样的可怜虫会花几个小时来追踪这样的问题。

于 2013-08-06T03:46:44.163 回答
1

有时您不能依赖自动模板专业化。我以前在 VS 中遇到过这种情况,最终不得不明确表示。 IE

Demonstrate<Foo>("foo:", &example)
于 2013-08-06T02:04:34.627 回答