泛型是程序設計語言的一種特性。容許程序員在強類型程序設計語言中編寫代碼時定義一些可變部分,那些部分在使用前必須做出指明。ios
各類程序設計語言和其編譯器、運行環境對泛型的支持均不同。將類型參數化以達到代碼複用提升軟件開發工做效率的一種數據類型。程序員
數據的值能夠經過函數參數傳遞,在函數定義時數據的值是未知的,只有等到函數調用時接收了實參才能肯定其值。這就是值的參數化。ide
#include<iostream> using namespace std; //比較int類型大小 int myMax(int a, int b) { return a>b ? a : b; } //比較double類型大小 double myMax(double a, double b) { return a>b ? a : b; } int main() { //針對不一樣類型求最大值 cout << myMax(10, 20) << endl; cout << myMax(1.22, 3.44) << endl; return 0; }
在C++中,數據的類型也能夠經過參數來傳遞,在函數定義時能夠不指明具體的數據類型,當發生函數調用時,編譯器能夠根據傳入的實參自動推斷數據類型。這就是類型的參數化。函數
template<typename T> T max(T a, T b) { return a > b ? a : b; }
max<int>(2, 3);
函數模板表明一個函數族,它所用到的數據的類型(包括返回值類型、形參類型、局部變量類型)能夠不具體指定,而是用一個標識符來代替。函數調用時根據實參逆推出真正類型,生成具體函數的二進制代碼。spa
template <typename 類型參數1, typename 類型參數2, ...> 返回值類型 函數名(形參列表) { //模板函數體 }
typename能夠用class替換.此處class不是表示類,由於早期C++沒有typename而是用class表示類型參數名字。設計
函數名<參數類型1,參數類型2>(形參表); 函數名(形參表);
編譯器根據調用函數模板提供的模板實參,將所調用的函數模板編譯成具體函數的過程,稱爲函數模板的實例化。指針
函數模板是二次編譯。編譯器第一次看到函數定義,檢查語法,生成內部結構。第二次,將提供的具體類型實參結合以前內部結構生成具體函數二進制指令。ci
隱式推斷的同時不能作隱式類型轉換開發
#include<iostream> using namespace std; //函數模板 template<typename T> void fun(T const& a, T const& b) { cout << typeid(a).name() << " " << typeid(b).name() << endl; } template<typename T1, typename T2> void foo(T1 const& a, T2 const& b) { cout << typeid(T1).name() << " " << typeid(T2).name() << endl; } int main() { fun(10, 5); //fun(5, 10.0); //隱式推斷的同時不能作隱式類型轉換 foo(5, 10.0); //增長一種類型便可 cin.get(); return 0; }
重載優先選擇普通版本字符串
#include<iostream> using namespace std; #include<string> //任意類型大小 template<typename T> T const& myMax(T const& a, T const& b) { cout << "<TT>" << flush << endl; return a>b ? a : b; } //任意指針類型大小 template<typename T> T* const& myMax(T* const& a, T* const& b) { cout << "<T* T*>" << flush << endl; return a>b ? a : b; } //C風格字符串的最大值 //const char* myMax(char const*a, char const*b) //加const&是爲了防止拷貝構造 const char* const& myMax(char const* const& a, char const* const& b) { cout << "const char* const&" << endl; return strcmp(a, b)>0 ? a : b; } int main() { const char* a = "abc"; const char* b = "def"; const char* c = "xyz"; //重載優先選擇普通版本,除非函數模板能提供更好更匹配的函數 myMax(a, b); //比較任意類型大小 myMax(10, 10); //選擇普通版本 myMax((char*)a, b); //調用模板 myMax<>(a, b); myMax<const char*>(a, b); cin.get(); return 0; }
const char* const& <TT> const char* const& <T* T*> <TT>