【C++】分离编译模式与函数模板

一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件连接起来形成单一的可执行文件的过程称为分离编译模式
开发中普遍的做法是,函数声明和实现进行分离,每个函数的具体实现写在 cpp 文件,而函数声明写在 .h 文件,其他文件要用到函数时需要先 include 对应的头文件。
但是,在定义和调用函数模板时如果也采用这种方式,则可能会产生链接错误
因为函数模板是一种通用的函数声明,其中包含了一个或多个类型参数。函数模板并不是实际的函数定义,而是定义了如何生成具体类型的函数。函数模板的定义描述了函数的形式,但没有为特定的类型提供实现。
而实例化是指使用特定类型参数将函数模板转化为实际的函数定义的过程。当在代码中使用函数模板并提供了具体的类型参数时,编译器会根据这些类型参数生成对应的函数定义。
当函数模板(具体实现的代码)在当前文件,且在当前文件调用它时,编译器会进行隐式实例化:
在这里插入图片描述
而当采用分离编译模式,因为函数模板所在的文件中没有函数调用,编译器则不会根据模板进行实例化,当其他文件想要调用这个函数时,尽管通过引用头文件包含了函数模板的函数声明,但是由于缺少函数模板本身,所以也不会进行实例化:
在这里插入图片描述
进入链接阶段,将检查所引用的函数能否正确链接,此时因为并没有实例化出 add 的定义,所以会抛出“未定义”的错误:
在这里插入图片描述

一种解决方法是将函数模板写在头文件中,这样每当其他文件 include 头文件并调用函数时,因为当前文件存在函数模板且出现了函数调用,编译器将会根据函数模板实例化出函数定义。但是这样不符合分离编译模式的规则,因为分离编译模式要求函数原型声明放在头文件,定义放在源文件。
更好的解决方式是,在函数模板所在文件中进行显式实例化(也称为外部实例化),可以在不发生函数调用的时候根据函数模板进行实例化(或者在不使用类模板的时候根据类模板进行实例化),这样在链接时就能顺利找到函数的定义:

在这里插入图片描述

显式实例化必须和函数模板在同一个文件中,否则编译器将会因找不到函数模板而报错。

参考博文:

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值