今天编码的时候,发现了一个错误,就是模板代码在链接的时候找不到方法。
情况大概如下:
在 "Manager.h" 中
class Manager {
public:
template<typename T>
void SetData(const T& value);
};
然后在cpp文件中定义SetData
template<typename T>
void Manager::SetData(const T& value) {
}
在另外一个main.cpp文件中使用
#include "Manager.h"
Manager mgr;
double n = 0;
mgr.SetData(n);
这样就会产生一个error LNK2019:无法解析的外部符号 “public: void __thiscall Manager::SetData<double>(const double&)” xxxx,该符号在 xx函数中被引用的链接错误。查了一下书籍,错误的原因在于,function template SetData(const T&)的定义没有具现化,Manager.h和Manager.cpp是分开编译的,在编译main.cpp的过程中,编译器假设这个template的定义在某个地方,因而只生成一个对该定义的reference,并将这个reference所指的定义式留给链接器去决议,但是在链接期间,又找不到这样一个定义。
Note:奇怪的是,如果n是int类型,又可以编译成功,但是回家后,我用自己的电脑试了一下,VS2008,int类型的也不行
解决这个问题有几个方法:
1)采用置入式。也就是定义也放在头文件中
2)显示具现化一份声明。
即在cpp文件中声明如下 template void Manager::SetData(const double&); ,这样做就要为每一个类型做一份声明,比较繁琐
3)采用export关键字。它会export出除inline之外的其他方法
export template <typename T>
class Manager {
public:
void SetData(const T&); //这个声明就会被export
void Print() {}; //不会被export
};