一.函数模板的使用
泛型编程函数模板会自动类型推导调用,也可以显示类型调用。
1 int a = 0; 2 int b = 1; 3 4 Swap(a,b); //自动推导 5 6 float c = 2; 7 float d = 3; 8 9 Swap<float>(c, d); //显示调用
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 template < typename T > 7 void Swap(T& a, T& b) 8 { 9 T c = a; 10 a = b; 11 b = c; 12 } 13 14 template < typename T > 15 void Sort(T a[], int len) //选择排序 16 { 17 for(int i=0; i<len; i++) 18 { 19 for(int j=i; j<len; j++) 20 { 21 if( a[i] > a[j] ) 22 { 23 Swap(a[i], a[j]); 24 } 25 } 26 } 27 } 28 29 template < typename T > 30 void Println(T a[], int len) //打印数组元素数值 31 { 32 for(int i=0; i<len; i++) 33 { 34 cout << a[i] << ", "; 35 } 36 37 cout << endl; 38 } 39 40 int main() 41 { 42 int a[5] = {5, 3, 2, 4, 1}; 43 44 Println(a, 5); 45 Sort(a, 5); 46 Println(a, 5); 47 48 string s[5] = {"Java", "C++", "Pascal", "Ruby", "Basic"}; 49 50 Println(s, 5); 51 Sort(s, 5); 52 Println(s, 5); 53 54 return 0; 55 }
1 5, 3, 2, 4, 1, 2 1, 2, 3, 4, 5, 3 Java, C++, Pascal, Ruby, Basic, 4 Basic, C++, Java, Pascal, Ruby,
多参数函数模板:无法自动推导返回值类型,可以从左向右部分指定类型参数,函数模板中的返回值类型必须显示指定。
1 // T1 = int, T2 = double, T3 = double 2 int r1 = Add<int>(0.5, 0.8); //部分指定类型 3 4 // T1 = int, T2 = float, T3 = double 5 int r2 = Add<int, float>(0.5, 0.8); //部分指定类型,编译器根据实参0.8推导double 6 7 // T1 = int, T2 = float, T3 = float 8 int r3 = Add<int, float, float>(0.5, 0.8); //显示声明
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 template 7 < typename T1, typename T2, typename T3 > 8 T1 Add(T2 a, T3 b) 9 { 10 return static_cast<T1>(a + b); 11 } 12 13 14 int main() 15 { 16 // T1 = int, T2 = double, T3 = double 17 int r1 = Add<int>(0.5, 0.8); 18 19 // T1 = double, T2 = float, T3 = double 20 double r2 = Add<double, float>(0.5, 0.8); 21 22 // T1 = float, T2 = float, T3 = float 23 float r3 = Add<float, float, float>(0.5, 0.8); 24 25 cout << "r1 = " << r1 << endl; // r1 = 1 26 cout << "r2 = " << r2 << endl; // r2 = 1.3 27 cout << "r3 = " << r3 << endl; // r3 = 1.3 28 29 return 0; 30 }
结果:
1 r1 = 1 //函数返回值是int类型 2 r2 = 1.3 //函数返回值是double类型 3 r3 = 1.3 //函数返回值是float类型
重载函数模板:函数模板可以像普通函数一样被重载。
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 template < typename T > 7 T Max(T a, T b) //模板函数——求ab谁大(重载) 8 { 9 cout << "T Max(T a, T b)" << endl; 10 11 return a > b ? a : b; 12 } 13 14 int Max(int a, int b) //普通函数——求ab谁大 15 { 16 cout << "int Max(int a, int b)" << endl; 17 18 return a > b ? a : b; 19 } 20 21 template < typename T > 22 T Max(T a, T b, T c) //函数模板——求abc中谁大(重载) 23 { 24 cout << "T Max(T a, T b, T c)" << endl; 25 26 return Max(Max(a, b), c); //2次模板调用 27 } 28 //3个Max函数有重载关系,也能进行函数重载 29 30 int main() 31 { 32 int a = 1; 33 int b = 2; 34 //匹配的很好 35 cout << Max(a, b) << endl; // 普通函数 Max(int, int) 36 //提醒编译器优先使用 37 cout << Max<>(a, b) << endl; // 函数模板 Max<int>(int, int) 38 //匹配不好,用函数模板 39 cout << Max(3.0, 4.0) << endl; // 函数模板 Max<double>(double, double) 40 //3个参数 41 cout << Max(5.0, 6.0, 7.0) << endl; // 函数模板 Max<double>(double, double, double) 42 //这个例子好,有点迷惑人!'a'迷惑人,表现形式误解成char型 43 cout << Max('a', 100) << endl; // 普通函数 Max(int, int) 44 45 return 0; 46 }
结果:
1 int Max(int a, int b) 2 2 3 T Max(T a, T b) 4 2 5 T Max(T a, T b) 6 4 7 T Max(T a, T b, T c) 8 T Max(T a, T b) 9 T Max(T a, T b) 10 7 11 int Max(int a, int b) 12 100
二.类模板的使用
类模板注意点:只能显示指定具体类型,无法自动推导。
1 template < typename T > 2 class Operator 3 { 4 public: 5 T op(T a, T b); 6 };
1 Operator<int> op1; 2 Operator<string> op2; 3 int i = op1.op(1,2); 4 string s = op2.op("D.T.","Software");
类模板的工程应用:
类模板必须在头文件中定义,类模板不能分开实现在不同的文件中,类模板外部定义的成员函数需要加上模板<>声明。
Operator.h:
1 #ifndef _OPERATOR_H_ 2 #define _OPERATOR_H_ 3 4 template < typename T > 5 class Operator 6 { 7 public: 8 T add(T a, T b); //函数声明 9 T minus(T a, T b); 10 T multiply(T a, T b); 11 T divide(T a, T b); 12 }; 13 14 template < typename T > //模板<>声明 15 T Operator<T>::add(T a, T b) 16 { 17 return a + b; 18 } 19 20 template < typename T > 21 T Operator<T>::minus(T a, T b) 22 { 23 return a - b; 24 } 25 26 template < typename T > 27 T Operator<T>::multiply(T a, T b) 28 { 29 return a * b; 30 } 31 32 template < typename T > 33 T Operator<T>::divide(T a, T b) 34 { 35 return a / b; 36 } 37 38 #endif
Operator.cpp:
1 #include <iostream> 2 #include <string> 3 #include "Operator.h" 4 5 using namespace std; 6 7 int main() 8 { 9 Operator<int> op1; //显示声明模板 10 11 cout << op1.add(1, 2) << endl; //3 12 cout << op1.multiply(4, 5) << endl; //20 13 cout << op1.minus(5, 6) << endl; //-1 14 cout << op1.divide(10, 5) << endl; //2 15 16 return 0; 17 }
结果:
1 3 2 20 3 -1 4 2