是否在编译时创建了所有模板实例?

时间:2015-07-31 09:09:15

标签: c++ templates c++11 variadic-templates

在了解了使用递归的可变参数函数模板后,我想知道:

在编译时创建的程序执行期间是否需要可能的所有模板实例?是否有即时实例化的东西?

2 个答案:

答案 0 :(得分:3)

在将每个翻译的翻译单元转换为实例化单元的过程中实例化模板。

翻译单元本质上是一个源文件。

翻译的翻译单元(试着说快三倍)是没有模板实例化的编译输出。

实例化单元本质上是已翻译的翻译单元,其中模板已实例化。

实例化是否发生在“编译时”取决于实现的体系结构。

在传统的“编译到对象和链接对象”架构(大多数开发人员在windows或linux下工作的人都熟悉)中,翻译翻译单元的生成和实例化单元的生成都是阶段(可能是组合阶段)编译器。因此,在此模型中,实例化是一个编译时活动。

然而,有些实现使用“智能链接器”,并且编译器输出翻译的翻译单元,其中一些辅助信息描述了每个翻译的翻译单元需要哪些模板实例化。然后,链接器处理将它们转换为实例化单元的过程。通过这样的实现,模板即时化因此是链接时活动而不是编译时活动。这个构建模型的目的是为链接时优化提供机会(链接时模板实例化更多的是副作用而不是目标)。

我遇到的第一个带有智能链接器的实现可以作为Sun Microsystems在SunOS和更高版本Solaris上的附加成本选项(默认情况下带有包含更典型的哑链接器的工具链的操作系统)。我从那以后遇到过其他几个这样的工具链,但不能随便召回他们的供应商。

我不知道在运行时发生模板实例化的任何实现。但可以想象,C ++解释器可能会以这种方式工作。

答案 1 :(得分:1)

所有模板实例化都是在编译时创建的。 从标准引用:

N4296 2.2 / 1/8 [lex.phases]

  

翻译的翻译单元和实例化单元组合为   如下:[注意:部分或全部可以从库中提供。    - 结束注释] 检查每个翻译的翻译单元以产生一个   所需实例化列表。 [注意:这可能包括   已经明确要求的实例化(14.7.2)。 - 结束   注意事项] 找到所需模板的定义。确实如此   实现 - 定义是否是翻译单位的来源   需要包含这些定义。 [注意:一个   实现可以将足够的信息编码到翻译中   翻译单位,以确保此处不需要来源。 -   结束注释] 执行所有必需的实例化以生成   实例化单位。 [注意:这些与翻译类似   翻译单元,但不包含对未实例化的引用   模板,没有模板定义。 - 结束说明]该计划是   如果任何实例化失败,则格式不正确。