在C++中,数据的类型也能够经过参数来传递,在函数定义时能够不指明具体的数据类型,当发生函数调用时,编译器能够根据传入的实参自动推断数据类型。这就是类型的参数化。ios
函数模板是一种特殊的函数,可使用不一样的类型进行调用,对于功能相同的函数,不须要重复编写代码,而且函数模板与普通函数看起来很相似,区别就是类型能够被参数化。函数
函数模板的语法:spa
template <typename 类型参数1 , typename 类型参数2 , ...> 返回值类型 函数名(形参列表){ //在函数体中可使用类型参数 }
类型参数能够有多个,它们之间以逗号,
分隔。类型参数列表以< >
包围,形式参数列表以( )
包围。code
typename
关键字也可使用class
关键字替代,它们没有任何区别。C++ 早期对模板的支持并不严谨,没有引入新的关键字,而是用 class 来指明类型参数,可是 class 关键字原本已经用在类的定义中了,这样作显得不太友好,因此后来 C++ 又引入了一个新的关键字 typename,专门用来定义类型参数。不过至今仍然有不少代码在使用 class 关键字,包括 C++ 标准库、一些开源程序等。编译器
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; #if 0 //int类型数据交换 void MySwap(int& a, int& b){ int temp = a; a = b; b = temp; } //double类型 void MySwap(double& a, double& b){ double temp = a; a = b; b = temp; } #endif //模板技术 类型参数化 编写代码能够忽略类型 //为了让编译器区分是普通函数 模板函数 template<class T1,class T2> //template<typename T>告诉编译器 ,下面写模板函数 void MySwap(T& a, T& b){ T temp = a; a = b; b = temp; } void test01(){ int a = 30; int b = 20; //1 自动类型推导,编译器根据你传的值 进行类型自动推导 cout << "a:" << a << " b:" << b << endl; MySwap(a, b); cout << "a:" << a << " b:" << b << endl; double da = 12.3; double db = 21.1; cout << "da:" << da << " db:" << db << endl; MySwap(da, db); cout << "da:" << da << " db:" << db << endl; //2. 显式的指定类型 MySwap<int>(a, b); } int main(void){ test01(); return 0; }
函数模板跟普通函数同样,也能够被重载io
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; template<class T> int MyAdd(T a,T b){ return a + b; } //普通函数能够进行自动类型转换 //函数模板必须严格类型匹配 int MyAdd(int a,int c){ return a + c; } void test01(){ int a = 10; int b = 20; char c1 = 'a'; char c2 = 'b'; MyAdd<>(a,b);//限定只使用函数模板 MyAdd(a,c1);//这个调用,函数模板有更好的匹配,因而调用函数模板 MyAdd(a, b);//普通函数int MyAdd(int a,int c)已经能完美匹配,因而调用普通函数 MyAdd(c1,b);//这个调用,函数模板有更好的匹配,因而调用函数模板 } //函数模板被重载 template<class T> void Print(T a){ } template<class T> void Print(T a , T b){ } int main(void) { test01(); return 0; }