C++标准库提供了函数模板机制的支持,可以通过模板来生成不同类型的函数的实例,只需要对函数模板中的类型参数进行替换,替换成已经存在的类型,就能对同一函数的不同类型进行调用,完成函数定义的功能。
函数模板的定义
函数模板的定义可以使用关键字template,template关键字放在函数模板定义的最前面,其后面是用尖括号(<>)括起来得到的模板参数列表,其中各个参数可以是模板类型参数,也可以是非模板类型参数(相当于常量),然后就是函数声明部分,和普通的函数的声明是一样的,不同的是,函数声明与函数体中可以存在模板类型参数,代表一种类型下的参数。
模板类型参数需要使用C++中指定的关键字class或者typename来修饰,这样才能通过编译。而且,对于函数模板中class或者typename修饰的模板类型参数,可以是任意合法的标识符参数。
举个函数模板定义的例子:
template <typename T>
T template_sum(T *array, int size) {
int i;
T sum = 0;
for(i=0; i<size; i++) {
sum += array[i];
}
return sum;
}
上面的函数模板等价于
template <class C>
C class_sum(C *array, int size) {
int i;
C sum = 0;
for(i=0; i<size; i++) {
sum += array[i];
}
return sum;
}
使用typename或者class修饰模板类型参数是没有区别的,对于上面的函数模板,功能是实现对T或C类型数组中元素进行累加求和。
上面关于函数模板的定义中,说明了可以在模板类型参数类表中使用类型常量,例如:
template <typename T, typename M, int size>
T sum(T (&a)[size], M second) {
int i;
T total = 0;
for(i=0; i<size; i++) {
total += a[i];
}
total += second;
return total;
}
其中T和M是两个类型,而函数模板定义中指定了int size就是类型常量,因为它不需要替换成其它的类型,也就是它已经能够执行函数中涉及到的计算问题。
这个函数模板定义的功能是,对T类型的数组求和,之后再加上M类型的一个变量指定值,最后返回和值。
函数模板的实例化
定义的一个函数模板必须实例化以后才能被使用。实例化函数模板的概念,就是用已经存在的类型来替换函数模板中class和typename修饰的模板类型参数。当模板中模板类型参数被赋予实在的类型以后,就能根据函数指定的形参,用实参来执行函数计算的功能。
例如,对于上面两种情况中定义的函数模板,进行实例化,可以看到效果。
第一种情况:
#include <iostream>
using namespace std;
template <typename T>
T template_sum(T *array, int size) {
int i;
T sum = 0;
for(i=0; i<size; i++) {
sum += array[i];
}
return sum;
}
template <class C>
C class_sum(C *array, int size) {
int i;
C sum = 0;
for(i=0; i<size; i++) {
sum += array[i];
}
return sum;
}
int main() {
int ia[5] = {5,1,7,3,10};
cout<<template_sum(ia, 5)<<endl;
double da[4] = {1.22,3.51,8.02,5.78};
cout<<template_sum(da, 4)<<endl;
cout<<class_sum(ia, 5)<<endl;
cout<<class_sum(da, 4)<<endl;
return 0;
}
编译function.cpp文件,并运行,结果如下所示:
[root@bogon template]# g++ -o function function.cpp
[root@bogon template]# ./function
26
18.53
26
18.53
第二种情况:
#include <iostream>
using namespace std;
template <typename T, typename M, int size>
T sum(T (&a)[size], M second) {
int i;
T total = 0;
for(i=0; i<size; i++) {
total += a[i];
}
total += second;
return total;
}
int main() {
double da[5] = {1.22,4.01,5.00,3.27,7.87};
int i = 200;
cout<<sum(da, i)<<endl;
return 0;
}
编译consttemplate.cpp文件,并运行,结果如下所示:
[root@bogon template]# g++ -o ct consttemplate.cpp
[root@bogon template]# ./ct
221.37