重复的c ++模板实例化

时间:2011-04-04 10:44:27

标签: c++ templates

编译器是否可以跨多个翻译单元复制同一模板的实例化?

例如,如果你有一个在函数内部使用std:vector<int>的a.cpp,而b.cpp使用同样的东西,那么在最终的二进制文件中有两次std::vector<int>的风险吗?

4 个答案:

答案 0 :(得分:8)

这可能在项目编译时发生,因此不同的.obj文件将具有相同实例化的副本。当链接二进制文件时,链接器将消除实例化的所有冗余副本,因此结束二进制文件只有一个副本。

答案 1 :(得分:7)

正如sharptooth所说,最终的二进制文件只包含一个实例。但是每次在编译单元中遇到模板时,模板仍然会被实例化。如果你想要一些编译速度,在C ++ 0x中我们得到extern template s。它的工作方式与普通extern变量类似,因为它必须至少在一个编译单元中指定,但编译器不会在此单元中实例化模板。有关更多信息,请参阅herethis draft(14.7.2 [temp.explicit])。

答案 2 :(得分:0)

我认为编译器使用与普通类的成员函数相同的机制。它可以使它们成为inline,我认为它会留下链接器用来为最终二进制文件排序的信息。

唯一的区别是编译器“写入”定义 - 即模板的“实例化” - 但它在编译a.cpp或b.cpp

时设法完全相同的实例化

答案 3 :(得分:0)

这是可能的,但只有当你明确地实例化它们时,你才会遇到链接器错误:

// header.hpp
template< typename T >
class A
{
};

// source1.cpp
template class A< int >;

// source2.cpp
template class A< int >;

如果您没有明确地实例化模板,那么任何合适的链接器都可以轻松地删除副本。