编写一个函数比较两个值,并指出第一个值是小于丶等会还是大于第二个值,我们可能想要定义多个函数,每个函数比较一种给定类型的值:
//如果两个值相等,返回0,如果v1小返回-1,如果v2小返回1 int compare(const string &v1, const string &v2) { if (v1 < v2)return -1; if (v2 < v1)return 1; return 0; } int compare(const double &v1, const double &v2) { if (v1 < v2)return -1; if (v2 < v1)return 1; return 0; }
这两个函数几乎是相同的,唯一的差异就是参数的类型,函数体则完全一样。
函数模板
一个函数模板就是一个公式,可用来生成针对特定类型的函数版本,compare的函数模板如下:
template<typename T> int compare(const T &v1, const T &v2) { if (v1 < v2)return -1; if (v2 < v1)return 1; return 0; }
模板定义以关键字template开始,后跟一个模板参数列表,这是一个逗号分隔的一个或多个模板参数的列表,用<>包围起来。
tip:在模板的定义中,模板参数列表不能为空
compare函数声明了一个名为T的类型参数,在compare中,我们用名字T表示一个类型,而T表示的实际类型则在编译时根据compare的使用情况来确定。
实例化函数模板
当我们调用一个函数模板时,编译器用函数实参来推断模板实参。当调用compare时,编译器使用实参的类型来确定绑定到模板参数T的类型:
cout << compare(1, 2) << endl;//T为int
实参类型是int,编译器会推断出模板实参为int,并将它绑定到模板参数T。
编译器用推断出的参数模板来实例化一个特定版本的函数。当编译器实例化一个模板时,它使用实际的模板实参代替对应的模板参数来创建出模板的一个新“实例”:
//实例化出int compare(const int&,const int&) cout << compare(1, 0) << endl; //实例化出int compare(const vector<int>&,const vector<int>&) vector<int> vec1{ 1,2,3 }, vec2{ 4,5,6 }; cout << compare(vec1, vec2) << endl;//T为vector<int>
模板类型参数
类型参数可以用来指定返回类型或函数的参数类型,以及在函数体内用于变量声明或类型转换: