参考《深入浅出C++模板编程》
两个函数由同一模板生成,完全等价,则这两个函数为重复模板实例。C++对重复模板实例的解决方案是:在链接时识别及合并等价的模板实例。
示例代码
//-----------------------------------
//文件名caller1.cpp
#include <iostream>
template<typename T>
void func(T const &v)
{
std::cout << "func1: " << v << std::endl;
}
void caller1() {
func(1);
func(0.1);
}
//-----------------------------------
//文件名caller2.cpp
#include <iostream>
template<typename T>
void func(T const &v)
{
std::cout << "func2: " << v << std::endl;
}
void caller2() {
func(2);
func(0.2f);
}
//-----------------------------------
//文件名main.cpp
void caller1();
void caller2();
int main()
{
caller1();
caller2();
return 0;
}
输出如下:
func1: 1
func1: 0.1
func1: 2
func2: 0.2
在函数caller2()中本意是调用caller2.cpp中的func<int>,所以应该输出func2 : 2,但是caller1.cpp与caller2.cpp中均有func<int>实例,并且函数参数列表也相同(都为空),那么在链接时链接器基于函数名、模板实参列表以及参数列表判断两个函数模板实例等价,而将caller2.cpp中的func<int>除名。所有func<int>的调用都被链接到caller1.cpp中的func<int>实例。caller1()和caller2()中还分别调用了func<double>(无修饰浮点常数默认是double型)及func<int>。由于模板参数类型不同,这是两个不同的函数。
链接器不考虑函数具体内容,仅仅通过函数名、模板实参列表以及参数列表等“接口”信息来判断两个函数是否等价。