调用模板函数时,编译器根据调用参数推断出模板参数,用来实例化一个特定版本的函数。
template<typename T> T Add(T a, T b) { return a + b; } template<typename T,typename U> T Add(T a, U b) { return a + b; } //模板特例化,template后跟一对空的<>,并为所有模板参数提供实参 template<> char *Add(char *a, const char *b) { return strcat(a, b); } int Add(int, int) { cout << "!!!" ; return 0; } int main() { Add(1, 2);//普通函数优先于模板 Add(1.2, 2.3);//编译器自动推断模板参数类型 Add(1LL, 2);//编译器自动推断模板参数类型 Add(1, 'a');//编译器自动推断模板参数类型 Add<double, long long>(1, 'a');//指定类型 char buff[100] = "Hello"; Add(buff, "World");//特例化的优于普通的模板 return 0; }
模板再使用时才会实例化,产生对应类型的二进制代码。如果没有实例化,则编译生成的obj文件中不存在模板相关的代码,所以模板的声明和实现都放在头文件中。否则会发生链接错误,因为只有声明,没有实现。