类模板的定义和成员函数定义文件分离问题[转]

我把类模板的声明放在头文件中,把定义在类模板外部的成员函数放在CPP文件中。(VC6)
结果,在链接时出错:
mytemp.obj : error LNK2001: unresolved external symbol "public: int __thiscall Queue<int>::remove(void)"
mytemp.obj : error LNK2001: unresolved external symbol "public: void __thiscall Queue<int>::add(int const &)"

找了一下原因:
Code references something (such as a function, variable, or label)
that the linker can't find in the libraries and object files.

  Possible causes
* What the code asks for doesn't exist (the symbol is spelled incorrectly or uses the wrong case, for example).
* The code asks for the wrong thing (you are using mixed versions of the libraries, some from one version of the product, others from another version).

原来有两种编译模式:

包含编译模下类模板的成员函数和静态成员的定义必须被包含在要将它们实例化的所有文件中。
对于类模板定义中被定义为inline 的内联成员函数这是自动发生的。
但是如果一个成员函数被定义在类模板定义之外,那么这些定义应该被放在含有该类模板
定义的头文件中。

成员函数定义很大可能会描述实现细节,而用户可能不想知道或者我们希望向用户隐藏这些细节。而且在多个文件之间编译相同的函数模板定义可能会增加不 必要的编译时间。如果使用分离编译模式则允许我们把类模板接口即类模板定义与它的实现即它的成员函数和静态数据成员的定义分离。

分离编译模式 下类模板定义和其inline 成员函数定义都被放在头文件中而非inline成员函数和静态数据成员被放在CPP程序文本中。类模板必须以一种特殊的方式来声明——声明为exported 可导出的类模板。
可导出的类模板是指这样一个模板:当它的成员函数实例或静态数据成员实例被使用时,编译器只要求类模板的定义。如果一个文件要使用这些成员,它可以省略这些成员的定义。可导出的类模板的声明是在类模板的定义或者声明的关键字template 之前加上关键字export:
export template <class Type>

链接:http://www.cnblogs.com/OpenSchema/articles/193700.html

原文地址:https://www.cnblogs.com/ShowJoy/p/3642340.html