缴费医疗保険亇人:模板函数的定义和声明须在同一文件内

来源:百度文库 编辑:中财网 时间:2024/04/26 00:59:47

按照C++中代码的惯例,类声明在h文件中,类定义在cpp文件中,相应的成员函数声明也在h文件中,定义在cpp文件中。但是如果这样的架构用在模板函数中,在调用模板函数的地方链接器便会报错,error LNK2001: unresolved external symbol。将定义写在与声明相同的文件中问题解决,解释如下:

 

“大部分编译器在编译模板时都使用包含模式。也就是一般使用的把模板放到头文件中再包含。
当你不使用这个模版函数或模版类,编译器并不实例化它。当你使用时,编译器需要实例化它。因为编译器是一次只能处理一个编译单元,也就是一次处理一个cpp文件,所以实例化时需要看到该模板的完整定义,所以都放在头文件中。
这不同于普通的函数,在使用普通的函数时,编译时只需看到该函数的声明即可编译,而在链接时由链接器来确定该函数的实体。”

 

"temp.h:
void fun(T);

temp.cpp:
#include "temp.h"
void fun(T){}

main.cpp:
#include "temp.h"
void main()
{
    int a;
    fun(a);
}

由于main.cpp用到了fun(a),所以在编译main.cpp的时候,编译器知道它要用int来实例化fun(T)中的T,也就是要实例化fun(int),而要实例化一个函数模板就必须要知道这个函数模板的定义,但是由于main.cpp和包含函数模板定义的temp.cpp是分开编译的,所以编译器在编译main.cpp的时候就不能够用int来实例化fun(T),这样编译器就只能够把fun(a)当成一个外部符号,交由linker来resolve。
另外编译器在编译temp.cpp的时候,同样因为temp.cpp和main.cpp是分开编译的,所以此时编译器并不知道main.cpp中用到了fun(a),所以此时编译器虽然知道函数模板的定义,但也不会去实例化任何fun,当然就不会用int来实例化fun了。
结果就是,你在main.obj引用了外部符号fun,但是在temp.obj中不存在fun,所以linker就会报告无法解析的外部符号了。"

 

这里引用了xzgyb和John Titor对该问题的解释。

http://topic.csdn.net/t/20050722/09/4160766.html