// a.h
template<class T>
T Add(const T& left, const T& right);
// a.cpp
template<class T>
T Add(const T& left, const T& right)
{
return left + right;
}
// main.cpp
#include"a.h"
int main()
{
Add(1, 2);
Add(1.0, 2.0);
return 0;
}
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?我们开始运行
问题:会出现链接错误。
原因:首先程序运行是要预处理,编译汇编和链接。对于头文件的内容,a.cpp .i .s .o模板都是空的,因为编译器下不了手,不知道T是啥。(模板是在编译阶段处理,不是预处理)
main.cpp 里面因为只有声明,所以call是不知道地址的
然后链接的时候,因为a.cpp是没有生成对应的函数的(因为之前T不知道),所以链接的时候会发生链接错误。
简单说就是编译的时候经过模板的定义了但是因为T不知道所以不会生成对应的汇编代码,导致最后main.cpp里面要调用的时候并没有生成对应的函数所以会出现链接错误。
解决:
- 放在一个名为 .hpp 的文件,也是就是这个文件是.h和.cpp的合体,寓意更好。直接.h也可以哈。(推荐)
- 对于上面的原因对症下药,因为只有声明没有生成对应的定义,所以我们直接在 a.cpp 文件 显示实例化指定?在定义的下面加上:
template
int Add<int>(int& left, int& right);
template
double Add<double>(double& left, double& right);
为什么:
但是为什么放在一起就没有链接错误了?
因为声明和定义放在一起,调用函数的时候直接实例化call地址去了,所以不报错并不是因为链接能找到,而是根本没有去找,直接call地址了。