为什么模板不支持分离式编译?

概念了解

分离式编译

一个项目由若干个源文件共同实现,而每个源文件(.cpp)单独编译成目标文件(.obj),最后将所有目标文件连接起来形成单一的可执行文件(.exe)的过程。

编译过程

预处理–》编译–》汇编–》链接
  • 预处理阶段
    头文件展开、条件编译指令、宏替换
  • 编译阶段
    将第一步产生的文件同其他文件一起编译成汇编代码
  • 汇编阶段
    将汇编源码转换成可重定位目标文件
  • 链接阶段
    进行符号解析和重定位,将可重定位目标文件链接成可执行目标文件

模板

C++Primer中的定义:

模板是C++中泛型编程的基础。一个模板就是一个创建类或函数的蓝图或者说公式。
当使用一个vector这样的泛型类型,或者find这样的泛型函数时,我们提供足够的信息,将蓝图转换为特定的类或函数(实例化)。
这种转换发生在编译时。

我们可以捕捉到一个信息,使用的时候 对模板进行实例化,且发生在编译过程的编译阶段。

编译单元

在预处理阶段会进行头文件展开,通俗的理解就是.h+.cpp文件就是一个编译单元。

为什么模板不支持分离式编译

在编译阶段,每一个cpp文件都是相对独立的,并不知道另一个编译文件的存在,若存在外部调用,会在链接阶段进行重定位。
模板的实例化其实只能发生在本编译单元的调用。如果出现非本编译单元的模板调用,也就是分离式编译,只能等待链接时重定位,但是模板并没有实例化,所以会出现链接出错。

代码实例

模板函数声明在test.h中,定义在test.cpp中,调用在main.cpp中(链接出错)

[外链图片转存失败(img-kgFa3FKq-1566462362822)(./1.png)]
[外链图片转存失败(img-trFpMcC1-1566462362823)(./2.png)]

模板函数声明在test.h中,定义在main.cpp中,调用在main.cpp中(运行成功)

[外链图片转存失败(img-jiIazI4O-1566462362823)(./3.png)]
[外链图片转存失败(img-aVGzVKIt-1566462362823)(./4.png)]

模板函数声明在test.h中,定义在test.h中,调用在main.cpp中(运行成功,因为头文件会在预处理阶段对头文件展开)

[外链图片转存失败(img-eqKoMDGu-1566462362824)(./5.png)]

总结

这个简单的链接出错问题,其实原因涉及到了很多方面,经过分析,其实能够加深对编译过程的理解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值