我有一个与此相当的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"
。这必须是一些项目设置的事情,但是什么?
答案 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)