C++ C++;模板函数,相同类型,多个实例化:共享同一个代码副本?即使在不同的cpp/对象文件中 例如,考虑下面的代码: // f.h template <typename T> int f(T x) { return x+1; }

C++ C++;模板函数,相同类型,多个实例化:共享同一个代码副本?即使在不同的cpp/对象文件中 例如,考虑下面的代码: // f.h template <typename T> int f(T x) { return x+1; },c++,C++,及 最终程序是否只使用一个代码副本?当bar.cpp被隐藏,但仅提供对象文件bar.o时,是这样吗 我认为,由于每个cpp文件都是独立编译的,foo.o和bar.o都必须包含f(int)。链接器应该看到相同的重复签名,并且只使用一个副本。我说的对吗?是的,链接器通常会折叠重复的相同模板实例化。当涉及到模板时,这样做是为了避免二进制大小爆炸,并保持一些标准的不变量,例如函数指针的等价性。这种行为有时被称为按名称折叠 除此之外,即使内容完全相同(即编译相同的代码),也会折叠掉所有符号,即使它们不是来

最终程序是否只使用一个代码副本?当
bar.cpp
被隐藏,但仅提供对象文件
bar.o
时,是这样吗


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

是的,链接器通常会折叠重复的相同模板实例化。当涉及到模板时,这样做是为了避免二进制大小爆炸,并保持一些标准的不变量,例如函数指针的等价性。这种行为有时被称为按名称折叠


除此之外,即使内容完全相同(即编译相同的代码),也会折叠掉所有符号,即使它们不是来自相同的定义。这有时被称为按值折叠,但除非小心操作,否则可能会破坏标准的字母(即,因为指向不同函数的函数指针现在比较相等)。

每个实现都使用自己的方法,请参阅在获得程序之前,它会经过编译阶段和链接器阶段。我不确定它是什么时候被删除的,但如果要用同一个实例化模板的两个副本创建一个完整的程序,它肯定是世界上最糟糕的IDE。
//foo.cpp instantiation:
int i = f(1);
//bar.cpp instantiation:
int j = f(2);