我正在阅读一本关于模板如何工作的书,但我很难理解对模板的这种解释。
它说
当编译器看到模板的定义时,它不会 生成代码。它仅在我们实例化模板的特定实例时生成代码。代码仅在我们使用模板时生成(而不是在定义模板时)这一事实会影响我们组织源代码的方式以及检测到错误的方式…要生成实例化,编译器需要具有定义函数模板或类模板成员函数。因此,与非模板代码不同,模板的标头通常包括定义和声明。
“生成代码”到底是什么意思?与常规函数或类相比,我不明白编译函数模板或类模板有什么不同。
原文由 FrostyStraw 发布,翻译遵循 CC BY-SA 4.0 许可协议
编译器为模板类实例化中给出的特定类型 生成 代码。
例如,如果您有一个模板类声明
只要你有例如以下实例
这些将 有效地生成 与您定义的类相同的可链接代码,例如
和
并实例化变量,如
关于模板 定义(无论模板如何都不要与 声明 混淆)需要与头(包含)文件一起查看这一点,原因很清楚:
编译器无法在没有看到 定义 的情况下生成此代码。它可以指的是在链接阶段首先出现的匹配实例。
非模板类/成员/函数的声明为链接器提供了预定义的入口点。该定义可以从已编译目标文件(== .cpp == 编译单元)中看到的单个实现中得出。
相反,模板化类/成员/函数的声明可以从给定相同或不同模板参数的任意编译单元实例化。这些模板参数的定义至少需要查看一次。它可以是通用的或专用的。
请注意,无论如何您都可以为特定类型专门化模板实现(包含在标头中或在特定的 编译单元 中)。如果您要在您的一个 编译单元 中为您的模板类提供专门化,并且不要将您的模板类与除专门化之外的类型一起使用,那么将它们链接在一起也应该足够了。
我希望这个示例有助于阐明编译器的不同之处和所做的努力。