例如,考虑以下代码:

// f.h
template <typename T>
int f(T x) {
   return x+1;
}

如果我们同时在foo.cppbar.cpp中实例化它:
//foo.cpp instantiation:
int i = f(1);


//bar.cpp instantiation:
int j = f(2);

最终程序将仅使用一个代码副本吗?是这样的,当bar.cpp隐藏时,仅提供了目标文件bar.o吗?

我认为,由于每个cpp文件都是独立编译的,因此foo.obar.o都必须包含f(int)。链接器应该看到相同的重复签名,并且只能使用一个副本。我对吗?

最佳答案

是的,链接器通常会将重复的相同模板实例折叠掉。这样做非常需要避免涉及模板时二进制大小的爆炸,并保持一些标准的要求不变性,例如功能指针的等效性。这种行为有时被称为折叠。

除此之外,some linkers甚至会折叠所有碰巧内容相同的符号(即,编译相同的代码),即使它们并非源自相同的定义。有时将其称为按值折叠,但除非仔细进行,否则可能会破坏标准的含义(即因为指向不同函数的函数指针现在比较相等)。

09-04 18:01
查看更多