(C++)模板分离编译面对的问题

这篇具有很好参考价值的文章主要介绍了(C++)模板分离编译面对的问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

什么是分离编译

一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。

模板的分离编译

假如有以下场景,模板的声明与定义分离开,在头文件中进行声明,源文件中完成定义:

//test.h
#include<iostream>
using namespace std;

//函数模板的声明
template<class T>
T Add(const T& left, const T& right);

//test.cpp
#include"test.h"
template<class T>

//函数模板的定义
T Add(const T& left, const T& right)
{
 return left + right;
}
//amin.cpp
#include"a.h"
int main()
{
 Add(1, 2);

 return 0;
}

如果模板进行分离编译会发现程序会出现链接错误,错误提示如下:
(C++)模板分离编译面对的问题正常的函数进行分离编译不会有任何问题,而函数模板进行分离编译却会出现链接错误,这是为什么?

我们都知道一个程序要先经过编辑、编译、链接,才能运行,而上面的模板分离编译的链接错误,不就是链接阶段发生的吗?那让我们一起看看链接之前会发生什么。
我们将一个程序的代码编辑完之后,就会进入编译阶段,而编译阶段又可以细分为预处理、编译、汇编,看看它们分别发生了什么?
预处理:源文件中头文件的展开/宏替换/条件编译/去掉注释

上面模板的分离编译中会将test.h在test.cpp和main.cpp中展开,那两个源文件中就都有了函数模板的声明,这一步是没有问题的。

编译:进行语法检查、生成汇编代码

在进行语法检查的时候,main.cpp中调用了模板函数,而在它调用之前已经有了函数模板的声明,说明语法没有问题,然后生成对应的汇编语言(要注意,调用函数肯定需要对应的函数地址,但现在只有函数的声明,那它的函数地址就是有待确定的)。而test.cpp中函数的定义在在这一阶段是需要被实例化的,但因为函数模板的模板参数无法确定类型,所以无法将函数模板实例化,也就无法生成对应的函数地址,那符号表中也就无法找到该函数的地址,但语法并没有问题(如果是普通函数,那就可以生成对应的函数地址)。

汇编:将汇编代码转换成机器码。其实只要上面的编译不检查出语法错误,那这一阶段就能进行。

经过以上阶段,就该进行链接了,前面main.cpp编译生成的汇编代码里待查的函数地址就要去符号表中找,但因为函数模板的定义并没有被实例化,符号表中并没有对应的函数地址,那main.cpp中调用的模板函数不就相当于找不到了吗,那就会报链接的错误

那如何解决呢?
方法一:既然是因为编译阶段test.cpp中函数模板无法确定类型而无法实例化,那我们可以保持模板分离编译不表,然后在test.cpp中显示实例化。加上如下代码:

template
double Add<int>(const int& left,const int& right);

这样虽然解决当前的问题,但如果调用函数时类型变成了double类型,那又得显示实例化,这样太麻烦了。

方法二:如果函数模板的声明和定义要分离也要都放在一个文件中(比如上面就是放在test.h中),那这样编译阶段就函数模板的模板类型可以确定,也就可以生成对应的函数地址。链接时就不会出问题了。很明显方法二更好。文章来源地址https://www.toymoban.com/news/detail-402439.html

到了这里,关于(C++)模板分离编译面对的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】模板进阶--非类型模板参数&&模板特化及分离编译

    模板参数分为 类型形参 与 非类型形参 ,其中,类型形参即出现在模板参数列表中,跟在class或者typename之类的参数类型名称,非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用 我们以定义一个静态的数组为例,在没有非

    2023年04月23日
    浏览(46)
  • 【C++学习】模板进阶——非类型模板参数 | 模板的特化 | 分离编译

    🐱作者:一只大喵咪1201 🐱专栏:《C++学习》 🔥格言: 你只管努力,剩下的交给时间! 模板我们之前一直都在使用,尤其是在模拟STL容器的时候,可以说,模板给类增加了更多的可能性,是C++最重要的部分之一。下面本喵来更深入的讲解一下模板。 在上面代码中,创建了

    2023年04月13日
    浏览(38)
  • 【C++】模板进阶—非类型模板参数、模板特化及模板的分离编译

    🚀 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。 🚁 个人主页:不 良 🔥 系列专栏:🛸C++  🛹Linux 📕 学习格言:博观而约取,厚积而薄发 🌹 欢迎进来的小伙伴,如果小伙伴们在学习的过程中,发现有需要纠正的地方,烦请指正,希望能够与诸君一同

    2024年02月16日
    浏览(39)
  • 【C++初阶(十)】C++模板(进阶) ---非类型模板参数、模板的特化以及模板的分离编译

    本专栏内容为:C++学习专栏,分为初阶和进阶两部分。 通过本专栏的深入学习,你可以了解并掌握C++。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:C++ 🚚代码仓库:小小unicorn的代码仓库🚚 🌹🌹🌹关注我带你学习编程知识 模板参数可分为类型形参和非类型形参。 类型形

    2024年01月18日
    浏览(38)
  • dedeCSM织梦模板添加301重定向跳转网址对的代码教程

    dedeCSM织梦模板添加301重定向跳转网址对的代码教程 dede5.7的程序中有自带的index.php 一般是这样: 实现301重定向   用下面代码替换原有的index.php内容: 可以直接复制上面的代码内容到dede5.7的根目录下的index.php中,把以前的源代码覆盖。 如何查看你的301重定向是否添加成功

    2024年02月02日
    浏览(68)
  • C++模板实现之谜:为何只能在头文件中?解密原因与高级分离技术

      概述: C++中模板必须在头文件中实现,因为编译器需要可见的实现以生成模板具体实例的代码。通过头文件,确保模板在每个编译单元中都能被正确展开,提高可维护性。 在C++中,模板只能在头文件中实现的主要原因是编译器在使用模板时需要生成对应的代码,而这部分

    2024年03月21日
    浏览(45)
  • 【问题记录】Unity编译ARCore模板项目问题

    Unity版本:2021.3.8f1c1 创建AR项目并下载使用默认模板,编译并发布到Android实机。 1、第一个问题: Error:Could not read cache value from\\\'C:UsersUsername.gradledaemon6.1.1registry.bin\\\'. 查询参考: 由 (5条消息) 安卓:Could not read cache value from\\\'C:UsersUsername.gradledaemon1.12registry.bin\\\'_Royel transfo

    2023年04月09日
    浏览(39)
  • 【C++初阶】想要编译器为你干活吗?来试试模板吧(模板初阶)

    我们之前都写过交换函数Swap,例如这样的: 如果要交换其它的类型该怎么办呢? 那只能当个CV工程师了,然后再修修改改,但是如果有很多类型呢?后期又需要改动该怎么办呢?一个一个函数的改吗?多个功能相同的函数,又会使程序 可读性降低,代码冗余 。 我们能用一

    2024年02月06日
    浏览(45)
  • 【C++】什么是函数模板/类模板?

    函数模板简单来说就是一个模板,与函数参数的类型无关,是一个模子,不是真正的函数,实例化的函数会根据实参的类型 自动 推导类型。 函数模板是一个模板,并不是真正的函数,它是根据传递过来的实参的类型实例化一个具体的函数,相当于我们将重复的事情交给了编

    2024年02月07日
    浏览(60)
  • 【C++】什么是模板?怎样使用模板?

    👀 樊梓慕: 个人主页  🎥 个人专栏: 《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》 🌝 每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.函数模板 1.1函数模板概念 1.2函数模板格式 1.3函数模板的实例化 1.4模板参数的匹配原则 2.类模

    2024年02月04日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包