函数模板(function template):
定义:函数模板不是一个实在的函数,编译器不能为其生成可执行代码。定义函数模板后只是一个对函数功能框架的描述,当它具体执行时,将根据传递的实际参数决定其功能。
格式:template <class 类型参数1,class 类型参数2,...>
示例:
template <class T>
T Inc(T n) {
return 1 + n;
}
? 不通过参数实例化函数模板
cout << Inc<double>(4) / 2; //输出:2.5
? 函数模板可以重载,只要它们的形参表或类型参数表不同即可。
?函数模板和函数的次序
在多个函数和函数模板名字相同的情况下,编译器如下处理一条函数调用语句:
1) 先找参数完全匹配的普通函数(非由模板实例化而得到的函数)。
2) 再找参数完全匹配的模板函数。
3) 再找实参经过自动类型转换后能够匹配的普通函数。
4) 上面的都找不到,则报错
template <class T>
T Max(T a, T b) {
cout << "TemplateMax" << endl;
return 0;
}
template <class T, class T2>
T Max(T a, T2 b) {
cout << "TemplateMax2" << endl;
return 0;
}
double Max(double a, double b) {
cout << "MyMax" << endl;
return 0;
}
int main(void)
{
int i=4,j=5;
Max(1.2,3.4); //output:MyMax
Max(i,j); //output:TemplateMax
Max(1.2,3); //output:TemplateMax2
return 0;
}
? 匹配函数模板时,不进行类型自动转换
template <class T>
T myFunction(T arg1, T arg2) {
cout << arg1 <<" "<< arg2 << endl;
return arg1;
}
...
myFunction(5,8.5); //error, no matching function for call to ‘myFunction(int, double)‘
? 函数模板示例:Map
实现把一个数组的某一段指定序列按照自定义类型转换规则转换后存到另一数组中。
1 #include <iostream>
2 using namespace std;
3 template <class T, class Pred>
4 void Map(T s, T e, T x, Pred op) {
5 for(; s != e; ++s, ++x) {
6 *x = op(*s);
7 }
8 }
9 double Square(double x) {
10 return x*x;
11 }
12 int main(void) {
13 int a[5] = {1,2,3,4,5}, b[5];
14 Map(a, a+5, b, Square);
15 for(int i=0; i<5; i++) {
16 cout << b[i] <<ends;
17 }
18 return 0;
19 }
执行Map(a, a+5, b, Square); 后,实例化以下函数:
void Map(int * s, int * e, int * x, double (*op)(double)) {
for(; s != e; ++s, ++x) {
*x = op(*s);
}
}
将a[]中的元素平方后存入b[]中。
2018-01-24