当前位置:首页 > 科技  > 软件

C++模板背后的黑箱操作:编译器

来源: 责编: 时间:2023-12-08 09:14:52 292观看
导读一、编译器如何处理模板1.模板代码的处理为了理解模板的复杂性,你需要了解编译器是如何处理模板代码的。当编译器遇到模板方法定义时,它会进行语法检查,但实际上不会编译模板。编译器不能编译模板定义,因为它不知道这些模

一、编译器如何处理模板

1.模板代码的处理

为了理解模板的复杂性,你需要了解编译器是如何处理模板代码的。当编译器遇到模板方法定义时,它会进行语法检查,但实际上不会编译模板。编译器不能编译模板定义,因为它不知道这些模板将用于哪些类型。编译器不可能为像 x = y 这样的代码生成代码,而不知道 x 和 y 的类型。87n28资讯网——每日最新资讯28at.com

87n28资讯网——每日最新资讯28at.com

当编译器遇到模板的实例化,例如 Grid<int>,它会通过将类模板定义中的每个 T 替换为 int 来为 int 版本的 Grid 模板编写代码。当编译器遇到模板的不同实例化,例如 Grid<SpreadsheetCell>,它会为 SpreadsheetCell 编写另一个版本的 Grid 类。编译器只是写出了如果没有模板支持,你需要为每种元素类型编写单独类时的代码。这里没有魔法;模板只是自动化了一个烦人的过程。如果你在程序中没有为任何类型实例化类模板,那么类方法定义就永远不会被编译。87n28资讯网——每日最新资讯28at.com

这种实例化过程解释了为什么你需要在定义的各个地方使用 Grid<T> 语法。当编译器为特定类型(如 int)实例化模板时,它会将 T 替换为 int,使 Grid<int> 成为该类型。87n28资讯网——每日最新资讯28at.com

2.选择性实例化

对于隐式类模板实例化,如以下示例:87n28资讯网——每日最新资讯28at.com

Grid<int> myIntGrid;

编译器总是为类模板的所有虚拟方法生成代码。然而,对于非虚拟方法,编译器只为你实际调用的那些非虚拟方法生成代码。例如,给定前面的 Grid 类模板,假设你在 main() 中写了这样的代码(仅此代码):87n28资讯网——每日最新资讯28at.com

Grid<int> myIntGrid;myIntGrid.at(0, 0) = 10;

编译器仅为 int 版本的 Grid 生成无参数构造函数、析构函数和非 const 的 at() 方法。它不会生成其他方法,如拷贝构造函数、赋值运算符或 getHeight()。这被称为选择性实例化。87n28资讯网——每日最新资讯28at.com

存在的风险是,某些类模板方法中的编译错误可能会被忽略。未使用的类模板方法可能包含语法错误,因为这些不会被编译。这使得测试所有代码的语法错误变得困难。87n28资讯网——每日最新资讯28at.com

你可以通过使用显式模板实例化来强制编译器为所有方法(虚拟和非虚拟)生成代码。以下是一个示例:87n28资讯网——每日最新资讯28at.com

template class Grid<int>;

注意:显式模板实例化有助于发现错误,因为它强制编译器编译所有即使未使用的类模板方法。使用显式模板实例化时,不要只尝试使用基本类型(如 int)实例化类模板,还要尝试使用更复杂的类型(如 string)。87n28资讯网——每日最新资讯28at.com

87n28资讯网——每日最新资讯28at.com

二、模板对类型的要求

1.类型独立的代码编写

当你编写与类型无关的代码时,必须对这些类型做出某些假设。例如,在 Grid 类模板中,你假设元素类型(由 T 表示)是可销毁的、可拷贝/移动构造的,以及可拷贝/移动赋值的。87n28资讯网——每日最新资讯28at.com

当编译器尝试用不支持类模板方法所使用的所有操作的类型来实例化模板时,代码将无法编译,且错误消息通常相当晦涩难懂。87n28资讯网——每日最新资讯28at.com

然而,即使你想使用的类型不支持类模板的所有方法所需的操作,你也可以利用选择性实例化来使用某些方法而不是其他方法。87n28资讯网——每日最新资讯28at.com

2.C++20 引入的概念(Concepts)

C++20 引入了概念(concepts),允许你为模板参数编写编译器可以解释和验证的要求。如果传递给模板实例化的模板参数不满足这些要求,编译器可以生成更易读的错误消息。后面将讨论概念。87n28资讯网——每日最新资讯28at.com

概念为模板编程增加了额外的类型安全性,它通过为模板参数提供一个明确的接口合约来实现。这种方式不仅可以防止类型不匹配的问题,还可以改善模板错误消息的可读性,从而使模板代码更容易维护和理解。87n28资讯网——每日最新资讯28at.com

87n28资讯网——每日最新资讯28at.com

三、类模板代码的文件

在类模板中,类模板定义和方法定义必须对任何使用它们的源文件可用。有几种机制可以实现这一点:87n28资讯网——每日最新资讯28at.com

1.方法定义与类模板定义在同一文件

你可以将方法定义直接放在定义类模板本身的模块接口文件中。当你在另一个源文件中导入这个模块以使用模板时,编译器将能够访问它所需的所有代码。这种机制用于之前的 Grid 实现。87n28资讯网——每日最新资讯28at.com

2.方法定义在单独的文件

或者,你可以将类模板方法定义放在一个单独的模块接口分区文件中。然后,你还需要将类模板定义放在自己的分区中。例如,Grid 类模板的主模块接口文件可能如下所示:87n28资讯网——每日最新资讯28at.com

export module grid;export import :definition;export import :implementation;

这导入并导出了两个模块分区:定义(definition)和实现(implementation)。类模板定义在定义分区中定义:87n28资讯网——每日最新资讯28at.com

export module grid:definition;import <vector>;import <optional>;export template <typename T> class Grid { ... };

方法的实现位于实现分区中,该分区还需要导入定义分区,因为它需要 Grid 类模板定义:87n28资讯网——每日最新资讯28at.com

export module grid:implementation;import :definition;import <vector>;...export template <typename T> Grid<T>::Grid(size_t width, size_t height)    : m_width { width }, m_height { height } { ... }

本文链接:http://www.28at.com/showinfo-26-39515-0.htmlC++模板背后的黑箱操作:编译器

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Python入门必备:细讲Python推导式

下一篇: 用 print 太慢了!强烈推荐这款 Python Debug 工具

标签:
  • 热门焦点
  • 小米平板5 Pro 12.4简评:多专多能 兼顾影音娱乐的大屏利器

    疫情带来了网课,网课盘活了安卓平板,安卓平板市场虽然中途停滞了几年,但好的一点就是停滞的这几年行业又有了新的发展方向,例如超窄边框、高刷新率、多摄镜头组合等,这就让安卓
  • 0糖0卡0脂 旭日森林仙草乌龙茶优惠:15瓶到手29元

    旭日森林无糖仙草乌龙茶510ml*15瓶平时要卖为79.9元,今日下单领取50元优惠券,到手价为29.9元。产品规格:0糖0卡0脂,添加草本仙草汁,清凉爽口,富含茶多酚,保留
  • 不容错过的MSBuild技巧,必备用法详解和实践指南

    一、MSBuild简介MSBuild是一种基于XML的构建引擎,用于在.NET Framework和.NET Core应用程序中自动化构建过程。它是Visual Studio的构建引擎,可在命令行或其他构建工具中使用
  • 每天一道面试题-CPU伪共享

    前言:了不起:又到了每天一到面试题的时候了!学弟,最近学习的怎么样啊 了不起学弟:最近学习的还不错,每天都在学习,每天都在进步! 了不起:那你最近学习的什么呢? 了不起学弟:最近在学习C
  • 慕岩炮轰抖音,百合网今何在?

    来源:价值研究所 作者:Hernanderz&ldquo;难道就因为自己的一个产品牛逼了,从客服到总裁,都不愿意正视自己产品和运营上的问题,选择逃避了吗?&rdquo;这一番话,出自百合网联合创
  • 大厂卷向扁平化

    来源:新熵作者丨南枝 编辑丨月见大厂职级不香了。俗话说,兵无常势,水无常形,互联网企业调整职级体系并不稀奇。7月13日,淘宝天猫集团启动了近年来最大的人力制度改革,目前已形成一
  • AI芯片初创公司Tenstorrent获三星和现代1亿美元投资

    Tenstorrent是一家由芯片行业资深人士Jim Keller领导的加拿大初创公司,专注于开发人工智能芯片,该公司周三表示,已经从现代汽车集团和三星投资基金等
  • OPPO K11样张首曝:千元机影像“卷”得真不错!

    一直以来,OPPO K系列机型都保持着较为均衡的产品体验,历来都是2K价位的明星机型,去年推出的OPPO K10和OPPO K10 Pro两款机型凭借各自的出色配置,堪称有
  • DRAM存储器10月价格下跌,NAND闪存本月价格与上月持平

    10月30日,据韩国媒体消息,自今年年初以来一直在上涨的 DRAM 存储器的交易价格仅在本月就下跌了近 10%,此次是全年首次降价,而NAND 闪存本月价格与上月持平。市
Top