在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; }