c++函数模板
一.函数模板
1.关于模板的使用
template:定义模板的关键字
typename:定义模板类型的关键字
T 通用的类型标识符
使用如下
template<typename T> //这样就写了一个模板
2.模板函数的作用
普通函数
int fun(int a, int b) {return a + b;
}
这个函数只能进行一种类型的加和
模板函数
template<typename T>
T fun(T a, T b) {return a + b;
}
模板函数,在调用函数时,模板类型可以通过实参自动推导(前提:在形参中用到了模板类型),这样就可以进行不同种类型的加和
3.确定函数模板类型的三种方式
1.显示指定
template<typename T>//T为int类型
void fun() {T b=0;cout << typeid(b).name() << endl;
}int main(){fun<int>();//显示指定为int类型return 0;
}
2.实参自动推导
template<typename T>//T为long类型
void fun(T b) {cout << typeid(b).name() << endl;
}int main(){long a=10;fun(a);//实参自动推导为long类型return 0;
}
3.默认的模板类型
template<typename T = long>//默认的模板类型T为long类型
void fun(T b) {cout << typeid(b).name() << endl;
}
注意:这三种确定函数模板类型的方式有优先级关系为 显示指定>实参自动推导>默认的模板类型
如下代码
template<typename T = long>//T最终类型为char类型
void fun(T b) {cout << typeid(b).name() << endl;
}int main(){int a=10;fun<char>(a);return 0;
}
4.模板的参数列表
1.函数模板的参数列表默认值不需要从右到左依次赋值
代码如下
template<typename M=char, typename T, typename K>//不会出现报错
2.函数模板参数列表比较好的顺序
前面:必须要显示指定的
中间:默认类型
最后:实参推导
代码如下
template<typename M, typename K=char, typename T >
void fun(T t) {T t1 = 0;K k = 0;M m = 0;//typeid(T).name() 这个是输出T的类型是什么cout << typeid(T).name() << endl;//输出为doublecout << typeid(K).name() << endl;//输出为charcout << typeid(M).name() << endl;//输出为long
}
int main(){fun<long>(1.1); return 0;
}
5.模板函数的实例化
1.模板函数会按需实例化出具体的函数
例如
template<typename T>
void fun(T b);//模板函数声明和定义可以分开写,但模板声明和定义都要写,这里是函数的声明int main(){fun(1.1);//这里会实例化出一个函数记为 函数1 下面展示 fun(1);//这里会实例化出一个函数记为 函数2 下面展示 return 0;
}template<typename T>//模板函数定义
void fun(T b) {cout << typeid(T).name() << endl;
}
//函数1
void fun<>(double b) {cout << typeid(double).name() << endl;
}
//函数2
void fun<>(int b) {cout << typeid(int).name() << endl;
}
2…模板函数的实例化是在编译单元文件内(源文件内),按需实例化(实例化是在编译期确定的)
注意:模板函数,声明和定义,应当(不是必须,也可以分开)放在一起
二.用函数模板优化冒泡排序(使之能给不同类型的数据排序)
未优化前
#include <iostream>
using namespace std;void BubbleSort(int parr[], int len) {for (int i = 0; i < len - 1; i++) {for (int j = 0; j < len - i - 1; j++) {if (parr[j]<parr[j+1]) {int temp;temp = parr[j];parr[j] = parr[j + 1];parr[j + 1] = temp;}}}
} int main() {int arr[] = { 1,5,64,7,2,6,1,4,5 };BubbleSort(arr, 9);for (int v : arr) {cout << v << " ";}return 0;
}
优化后
#include <iostream>
using namespace std;template<typename T>
bool rule_up(T t1,T t2) {//升序return t1 > t2;
}template<typename T>
bool rule_down(T t1, T t2) {//降序return t1 < t2;
}
template<typename T>
void BubbleSort(T parr[], int len,bool(*P_FUN)(T,T)) {//第三个参数是判断升序还是降序的for (int i = 0; i < len - 1; i++) {//进行排序for (int j = 0; j < len - i - 1; j++) {if ((*P_FUN)(parr[j],parr[j+1])) {//判断是否交换T temp;temp = parr[j];parr[j] = parr[j + 1];parr[j + 1] = temp;}}}
} int main() {//样例测试int arr[] = { 1,5,64,7,2,6,1,4,5 };BubbleSort(arr, 9,&rule_up);for (int v : arr) {cout << v << " ";}cout << endl;double arr2[] = {1.5,5.9,7.8,1.8,1.9,7.8,4.5 };BubbleSort(arr2, 7,&rule_down);for (double v : arr2) {cout << v << " ";}return 0;
}