函數模板是通用的函數描述,經過將類型做爲參數傳遞給模板,使編譯器生成可用具體的類型的函數。相似於:算法
template<class Any> void swap(Any &a, Any &b);
對於不一樣類型使用同一種算法,可以使用模板,有時須要像重載常規函數那樣去重載函數模板。編程
void swap(Any &a, Any &b); void swap(int &a, int &b);
假設:編輯器
struct job { char name[10]; int floor; };
假設咱們但願交換兩個job結構的內容,直接互換job便可,但有時候咱們只想交換name,不交換floor,但函數的參數列表是同樣的,沒法使用模板重載來提提供其餘的代碼,此時須要涉及到具體化函數的定義,即指定某個函數定義,再也不匹配模板。 ###實例化和具體化 在代碼中包模板自己不會生成函數定義,編譯器會根據具體參數類型生成模板的具體實例,這種叫隱式實例化。現在C++容許顯示實例化,意味着直接命令編輯器建立特定的實例,語法是在函數聲明前加template:函數
template void swap<int>(int &, int &);
此外還能夠顯示具體化(一下兩者等價)指針
template <> void swap<int>(int &, int &); template <> void swap(int &a, int &b);
隱式實例化,顯示實例化和具體實例化統稱具體化,都表示使用具體的函數定義,而不是通用描述。再聲明中使用前綴template和template<>來區分顯示實例化和具體化。顯示具體化必須有本身的定義,實例化不須要有本身的定義。 警告:試圖在同一個編程單元中使用同一類型的顯示實例和顯示具體化將出錯。 #具體化函數將覆蓋常規函數,而非模板函數將覆蓋具體化和常規模板!code
###編譯器的選擇 編譯器一般會對參數進行所須要的轉換,選擇是從最佳到最差的順序以下:圖片
template <class Type> void f(Type T); //#1 template <class Type> void f(Type *T); //#2 struct blot {int a, char b[10];}; blot link = {25, "sport"); f(&link);
f(&link)與#1,#2都匹配,具體參照徹底匹配,可是#2更具體,#1還須要將轉換爲指針,由於參數不須要再轉換已經具體化爲指針了。 ###徹底匹配容許的可有可無轉換 編譯器