重复的 c++模板实例化
编译器是否可以在多个翻译单元中复制同一模板的实例?
例如,如果您的 a.cpp 在函数内使用 std:vector
,并且 b.cpp 也使用相同的内容,则是否存在使用两次 std 的风险:最终二进制文件中的 :vector
?
Is it possible for the compiler to duplicate instantiations of a same template across several translation units?
For instance, if you have a.cpp which use a std:vector<int>
inside a function, and same thing for b.cpp, is there a risk of having two times std::vector<int>
in the final binary?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正如 Sharptooth 所说,最终的二进制文件将仅包含一个实例化。但每次在编译单元中遇到模板时,它们仍然会被实例化。如果您想要一些编译速度,在 C++0x 中我们可以使用
extern template
。它的工作方式与普通extern
变量类似,因为它必须在至少一个编译单元中指定,但编译器不会在该单元中实例化模板。请参阅此处和此草案 (14.7.2 [temp.explicit]) 了解更多信息。As sharptooth says, the final binary will only contain one instantiation. But the templates will still be instantiated everytime they are encountered in a compilation unit. If you want some compilation speed, in C++0x we get the
extern template
s. It works like normalextern
variables, in that it has to be specified in at least one compilation unit, but the compiler wont instantiate the template in this unit. See here and this draft (14.7.2 [temp.explicit]) for more infos.这可能在编译项目时发生,因此不同的 .obj 文件将具有相同实例化的副本。当链接二进制文件时,链接器将消除实例化的所有冗余副本,因此最终的二进制文件将只有一个副本。
This can happen while the project is being compiled, so different .obj files will have copies of the same instantiation. When the binary is linked the linker will eliminate all redundant copies of an instantiation, so the end binary will have only one copy.
这是可能的,但前提是您显式实例化它们,但随后您将收到链接器错误:
如果您没有显式实例化模板,那么任何合适的链接器都将轻松消除副本。
It is possible, but only if you explicitly instantiate them, but then you will get a linker errors :
If you are not explicitly instantiating templates, then any decent linker will easily eliminate copies.
我认为编译器使用与普通类的成员函数相同的机制。它可以使它们内联,我认为它会留下链接器用来整理最终二进制文件的信息。
唯一的区别是编译器“编写”定义 - 即模板的“实例化” - 但它在编译 a.cpp 或 b.cpp 时设法进行完全相同的实例化
I think that the compiler uses the same mechanism as with member functions of ordinary classes. It can make them
inline
and I presume that it leaves information around that the linker uses to sort it out for the final binary.The only difference is that the compiler 'writes' the definitions - that is the 'instantiation' of a template - but it manages to make exactly the same instantiation whilst compiling either of a.cpp or b.cpp