提出问题
1)常常出现函数参数类型不同但函数逻辑完全相同的情况
例如交换函数 Swap
1:交换两个整型变量
void Swap(int& a1, int& a2){
int tmp;
tmp = a1;
a1 = a2;
a2 = tmp;
}
2:交换两个double型变量
void Swap(double& a1, double& a2){
double tmp;
tmp = a1;
a1 = a2;
a2 = tmp;
}
2)两函数逻辑完全相同,仅参数表不同,那么如何做可以只写一个 Swap函数就能完成两个函数的功能?
解决方式_函数模板
1)函数模板形式如下所示:
template < class 参数类型1, class 参数类型2, … >
返回值类型名 模板名 ( 形参表 ) { 函数体; };
例如上述 Swap 函数:
template<class T2>
void Swap(T2& a1, T2& a2){
T2 tmp;
tmp = a1;
a1 = a2;
a2 = tmp;
}
2)在函数使用中,编译器会根据函数所提供的实参类型自动生成相应的函数
例如:
int main(){
int a = 2, b = 9;
Swap(a, b); //编译器自动生成void Swap(int& a1,int& a2);函数(模板实例化)
cout << a << " " << b<<endl;
double c = 1.2, d = 3.5;
Swap(c, d); //编译器自动生成void Swap(double& a1,double& a2);函数(模板实例化)
cout << c << " " << d<<endl;
return 0;
}
输出:
9 2
3.5 1.2
3)函数模板中可以有不止一个参数类型,例如:
template<class t1,class t2>
t2 print(t1 a1, t2 a2){
cout << a1 << " " << a2 << endl;
return a2;
}
4)示例:输出数组中最大的元素
template<class t>
t MaxElement(t* a, int size){
t Maxtmp = a[0];
for (int i = 1; i < size; ++i){
if (Maxtmp < a[i])
Maxtmp = a[i];
}
return Maxtmp;
}
int main(){
int a[5] = { 4, 3, 8, 54, 84};
cout << MaxElement(a, 5)<<endl;
return 0;
}
输出:
84
5)也可以不通过参数实例化模板
例如:
t2 print(t1 a1, t2 a2){
cout << a1 << " " << a2 << endl;
return a2;
}
int main(){
cout<<print<int, double>(4, 5.2)<<endl;
return 0;
}
输出:
4 5.2
5.2
6)函数模板可以重载,只要函数形参表和类型参数表不同即可
7)当出现多个函数和模板重载的情况下,编译器先找参数完全匹配的普通函数,再找参数完全匹配的函数模板,最后找通过实参类型转化可以匹配的普通函数
例如:
template<class t>
t Max(t a1, t a2){
cout << "TemplateMax" << endl;
return 0;
}
template<class t1,class t2>
t1 Max(t1 a1, t2 a2){
cout << "TemplateMax2" << endl;
return 0;
}
double Max(double a1, double a2){
cout << "MyMax" << endl;
return 0;
}
int main(){
int i = 2, j = 3;
Max(1.2, 1.3); //输出MyMax
Max(2, 3); //输出TemplateMax
Max(i, j); //输出TemplateMax
Max(1.2, 3); //输出TemplateMax2
return 0;
8)经典的函数模板示例:Map函数模板(将某一数组的某段的内容经过某种变化后赋给另一数组的某段位置)
template<class t,class h>
void Map(t* a, t* b, t* c, h op){
for (; a != b; ++a, ++c){
*c = op(*a);
}
}
int cub(int x){
return x*x*x;
}
double squ(double x){
return x*x;
}
int a[5] = { 1, 2, 3, 4, 5 }, b[5];
double c[5] = { 1.2, 2.3, 1.4, 2.5, 5.8 }, d[5];
int main(){
Map(a, a + 5, b, squ);
for (int i = 0; i < 5; ++i)
cout << b[i] << " ";
cout << endl;
Map(a, a + 5, b, cub);
for (int i = 0; i < 5; ++i)
cout << b[i] << " ";
cout << endl;
Map(c, c + 5, d, squ);
for (int i = 0; i < 5; ++i)
cout << d[i] << " ";
cout << endl;
return 0;
}
输出:
1 4 9 16 25
1 8 27 64 125
1.44 5.29 1.96 6.25 33.64