提出問題
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