在了解了使用递归的可变参数函数模板后,我想知道:
在编译时创建的程序执行期间是否需要可能的所有模板实例?是否有即时实例化的东西?
答案 0 :(得分:3)
在将每个翻译的翻译单元转换为实例化单元的过程中实例化模板。
翻译单元本质上是一个源文件。
翻译的翻译单元(试着说快三倍)是没有模板实例化的编译输出。
实例化单元本质上是已翻译的翻译单元,其中模板已实例化。
实例化是否发生在“编译时”取决于实现的体系结构。
在传统的“编译到对象和链接对象”架构(大多数开发人员在windows或linux下工作的人都熟悉)中,翻译翻译单元的生成和实例化单元的生成都是阶段(可能是组合阶段)编译器。因此,在此模型中,实例化是一个编译时活动。
然而,有些实现使用“智能链接器”,并且编译器输出翻译的翻译单元,其中一些辅助信息描述了每个翻译的翻译单元需要哪些模板实例化。然后,链接器处理将它们转换为实例化单元的过程。通过这样的实现,模板即时化因此是链接时活动而不是编译时活动。这个构建模型的目的是为链接时优化提供机会(链接时模板实例化更多的是副作用而不是目标)。
我遇到的第一个带有智能链接器的实现可以作为Sun Microsystems在SunOS和更高版本Solaris上的附加成本选项(默认情况下带有包含更典型的哑链接器的工具链的操作系统)。我从那以后遇到过其他几个这样的工具链,但不能随便召回他们的供应商。
我不知道在运行时发生模板实例化的任何实现。但可以想象,C ++解释器可能会以这种方式工作。
答案 1 :(得分:1)
所有模板实例化都是在编译时创建的。 从标准引用:
N4296 2.2 / 1/8 [lex.phases]
翻译的翻译单元和实例化单元组合为 如下:[注意:部分或全部可以从库中提供。 - 结束注释] 检查每个翻译的翻译单元以产生一个 所需实例化列表。 [注意:这可能包括 已经明确要求的实例化(14.7.2)。 - 结束 注意事项] 找到所需模板的定义。确实如此 实现 - 定义是否是翻译单位的来源 需要包含这些定义。 [注意:一个 实现可以将足够的信息编码到翻译中 翻译单位,以确保此处不需要来源。 - 结束注释] 执行所有必需的实例化以生成 实例化单位。 [注意:这些与翻译类似 翻译单元,但不包含对未实例化的引用 模板,没有模板定义。 - 结束说明]该计划是 如果任何实例化失败,则格式不正确。