C++如何链接模板实例
如果我在包含两个不同翻译单元的头文件中定义一个函数(可能是一个类成员函数但未内联),我会收到链接错误,因为该函数是多重定义的.模板并非如此,因为在编译器解析模板化类型的对象声明之前,它们不是可编译的类型.这让我意识到我不知道编译的模板代码在哪里以及它是如何链接的,因为 C++ 不只是创建代码的多个副本来定义 SomeTemplateClass.任何信息,将不胜感激.谢谢!
If I define a function (maybe a class member function but not inlined) in a header file that is included by two different translation units I get a link error since that function is multiply defined. Not so with templates since they are not compilable types until the compiler resolves a declaration of an object of a templatized type. This made me realize I don't know where compiled template code resides and how it is linked since C++ does not just create multiple copies of code to define SomeTemplateClass. Any info would be appreciated. Thanks!
推荐答案
C++编译器使用了3种实现方案:
There are 3 implementation schemes used by C++ compilers:
贪婪实例化,编译器在每个使用它的编译单元中生成一个实例化,然后链接器丢弃除其中一个之外的所有实例化(这不仅仅是代码大小优化,它是必需的,以便函数地址、
static
变量等都是唯一的).这是最常见的模型.
greedy instantiation, where the compiler generates an instantiation in each compilation unit that uses it, then the linker throws away all but one of them (this is not just a code-size optimization, it's required so that function addresses,
static
variables, and the like are unique). This is the most common model.
查询实例化,其中编译器有一个已经完成的实例化数据库.当需要实例化时,会检查并更新数据库.我知道的唯一使用它的编译器是 Sun 的,默认情况下不再使用它.
queried instantiation, where the compiler has a database of instantiations already done. When an instantiation is needed, the DB is checked and updated. The only compiler I know which uses this is Sun's, and it isn't used by default anymore.
迭代实例化,其中实例化由链接器进行(直接或通过将它们分配给编译单元,然后重新编译).这是 CFront 使用的模型 - 即历史上它是第一个使用的模型 - 以及使用 EDG 前端的编译器(与 CFront 相比进行了一些优化).
iterated instantiation, where the instantiations are made by the linker (either directly or by assigning them to a compilation unit, which will then be recompiled). This is the model used by CFront -- i.e. historically it was the first one used -- and also by compilers using the EDG front-end (with some optimisations compared to CFront).
(参见 C++ 模板,David Vandevoorde 和 Nicolai Josuttis 的完整指南.另一个在线参考是 http://www.bourguet.org/v2/cpplang/export.pdf,更关注编译模型,但仍然有实例化机制的描述).
(See C++ Templates, The Complete Guide by David Vandevoorde and Nicolai Josuttis. Another online reference is http://www.bourguet.org/v2/cpplang/export.pdf, which is more concerned about the compilation model but still has descriptions of the instantiation mechanisms).
相关文章