“未解析的外部符号”表示在标题中内联声明的模板化函数

时间:2013-08-06 01:51:38

标签: c++ visual-studio

我有一个与此相当的Visual Studio 2012项目:

Header.h

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

Source.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中定义但在此处不是时会发生这种情况。该函数在标题中内联定义。

可能导致此问题的原因以及如何解决?

修改

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

2 个答案:

答案 0 :(得分: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问题。另一方面,这里有一个可教的时刻:

不要以疯狂的方式使用MACROS来定义全球功能

否则像我这样的穷人会花费数小时追踪这样的问题。

答案 1 :(得分:1)

有时您不能依赖自动模板专业化。我之前遇到过这种情况并且最终必须要明确。

Demonstrate<Foo>("foo:", &example)