问题
写模板函数的时候,使用定义(a.h)与实现(a.cpp)分离的方式,结果一直报错对模板函数“未定义的引用”。使用nm命令查看a.o文件,发现没有模板函数的名字。很是奇怪。
原因
看了参考【1】(强烈建议看一下)才知道,这是因为C++标准规定,模板函数在没有被调用的时候,就不会被实例化。
因此main函数编译成.o文件时候,因为仅包含了a.h文件,没有模板函数的具体实现,只能寄希望于链接时ld在其他的.o(这里是a.o)文件中找到模板函数的实现,但是a.cpp编译成a.o文件的时候,因为a.cpp中没有调用模板函数的语句,因此不会将模板函数实例化,更不会将模板函数展开、编译到a.o文件中,因此a.o文件中也找不到模板函数的实现。这就导致了“未定义的引用”的出现。
解决
- 不要分离,把实现写在头文件中,主函数文件直接include这个头文件
- 在a.cpp中添加模板函数的显式示例化。更详细广泛的用法见参考【3】,包含了模板函数、模板类、模板类成员函数的显式实例化方法。
显式实例化方法为在 template 关键字后接函数的声明(不是定义),且函数标识符后接模板参数,如:template float twice<float>(float original);
拓展
类的模板成员函数