問題描述
如果我在包含兩個不同翻譯單元的頭文件中定義一個函數(可能是一個類成員函數但未內聯),我會收到鏈接錯誤,因為該函數是多重定義的.模板并非如此,因為在編譯器解析模板化類型的對象聲明之前,它們不是可編譯的類型.這讓我意識到我不知道編譯的模板代碼在哪里以及它是如何鏈接的,因為 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).
這篇關于C++如何鏈接模板實例的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!