C++模板函数 --接口与实现分离

问题

写模板函数的时候,使用定义(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文件中也找不到模板函数的实现。这就导致了“未定义的引用”的出现。

解决

  1. 不要分离,把实现写在头文件中,主函数文件直接include这个头文件
  2. 在a.cpp中添加模板函数的显式示例化。更详细广泛的用法见参考【3】,包含了模板函数、模板类、模板类成员函数的显式实例化方法。
    显式实例化方法为在 template 关键字后接函数的声明(不是定义),且函数标识符后接模板参数,如:
    template float twice<float>(float original);
    

拓展

类的模板成员函数
《Data Structures And Algorithms In Cpp》书中有一段话(来自附录A,P616),来自参考【2】。

Even with this, the issue now becomes how to organize the class template declaration and the member function template definitions. The main problem is that the implementations in Figure A.2 are not actually funtions; they are simply templates awaiting expasion. But they are not even expanded when the MemoryCell template is instantiated. Each member function template is expanded only when it is invoked.

这里说的一个要点是,即使类被实例化了,类模板成员函数也不会被实例化,只有类模板成员函数被调用的时候,才会被实例化。

但是貌似没有什么大的影响,只要把实现和接口写在一起,被主函数包含就行了,或者需要在写类成员模板函数实现的.cpp文件中,显式实例化类模板成员函数。

后话

搞了好几年编译了,原以为不会再被“undefined reference to ”难倒,但是没想到,同一个“undefined”,千千万万个理由。可能,这才是开始吧。

参考

[1]为什么C++编译器不能支持对模板的分离式编译
[2]细谈 C++ 类模板的分离式编译:类模板究竟要不要接口与实现分离
[3]显式模板实例化

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值