注意事项:
- 自动类型推导,必须推导出一致的数据类型T,才可以使用。
- 模板必须要确定出T的数据类型,才可以使用。
泛型:泛指类型。针对类型不确定,不明确的情况。
案例:
#include<iostream> using namespace std; // 函数模板案例:不同类型的数组进行排序。排序方法:选择排序。降序。 // 不同类型,这事就需要用到不定类型的泛型模板编程。 // 5、交换两元素位置函数 template<typename T> void mySwap(T& a, T& b) { T temp = a; a = b; b = temp; } // 1、排序函数 template<class T> void mySort(T arr[], int len) { for (int i = 0; i < len; i++) { int indexMax = i; for (int j = i+1; j < len; j++) { if (arr[j]>arr[indexMax]) { indexMax = j; } } // 2、如果最大值不是当前外循环下标:那么就需要将当前外循环下标元素与最大元素换位置。 if (indexMax!=i) { // 3、涉及到交换两个元素的位置,因为有第三个临时变量temp类型不定,所以采用泛型。 // 4、需要另外申明一个泛型函数。可抽离,可不抽离。 //mySwap(arr[i], arr[indexMax]); T temp = arr[i]; arr[i] = arr[indexMax]; arr[indexMax] = temp; } } } // 6、完事,我们希望把数组打印出来看看。这个数组类型还是不确定。 template<typename T> void printArr(T arr[], int len) { for (int i = 0; i < len; i++) { cout << arr[i] << " "; } cout << endl; } // 7、测试函数 void test01() { int arr[] = { 2, 5, 7, 9, 8, 6, 4, 3, 1 }; int len = sizeof(arr) / sizeof(int); mySort(arr, len); printArr(arr, len); char arr2[] = "dbeacfg"; int len2 = sizeof(arr2) / sizeof(char); mySort(arr2, len2); printArr(arr2, len2); } int main() { test01(); system("pause"); return 0; }
案例中要求:不同类型的数组,也就是说类型不定,这种情况就需要用到泛型。
所以在排序函数中,需要写泛型模板。
然后在排序中因为需要交换两个元素的位置,这两个元素类型也不确定,所以抽离一个泛型模板的交换函数。最后排序完成后,将结果打印出来。
普通函数与函数模板区别:隐式类型转换。
普通函数调用时可以发生自动类型转换(隐式类型转换)
函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换
如果利用显示指定类型的方式,可以发生隐式类型转换
//普通函数 int myAdd01(int a, int b) { return a + b; } //函数模板 template<class T> T myAdd02(T a, T b) { return a + b; } //使用函数模板时,如果用自动类型推导,不会发生自动类型转换,即隐式类型转换 void test01() { int a = 10; int b = 20; char c = 'c'; cout << myAdd01(a, c) << endl; //正确,将char类型的'c'隐式转换为int类型 'c' 对应 ASCII码 99 //myAdd02(a, c); // 报错,使用自动类型推导时,不会发生隐式类型转换 myAdd02<int>(a, c); //正确,如果用显示指定类型,可以发生隐式类型转换 } int main() { test01(); system("pause"); return 0; }
总结:建议使用显示指定类型的方式来调用函数模板,因为可以自己确定通用类型T。