1. 程式人生 > >C++函式模板的具體化和例項化

C++函式模板的具體化和例項化

C++函式模板----模板例項化、具體化 函式模板是C++新增的一種性質,它允許只定義一次函式的實現,即可使用不同型別的引數來呼叫該函式。這樣可以減小程式碼的書寫複雜度,同時也便於修改。 mark:使用函式模板並不會減少最終可執行程式的大小,因為在呼叫模板函式時,編譯器都根據呼叫時的引數型別進行形影的例項化。 函式模板的使用過程: struct job {     char name[20];     int salary; }; template <class T> //函式模板宣告,通用變數型別為T void swap(T &a, T &b); void showJob(const job &a);//列印job內容 using std::cin; using std::cout; using std::endl; void main(void) {     int a = 4;     int b = 5;     cout<<"Before swap a = "<<a<<" b="<<b<<endl;     swap(a, b);     cout<<"After swap a = "<<a<<" b="<<b<<endl;     job jobA = {"coder", 10000};     job jobB = {"manager", 1000};       cout<<"Before swap";     showJob(jobA);     showJob(jobB);     cout<<endl;     swap(jobA, jobB);     cout<<"After swap";     showJob(jobA);     showJob(jobB);     cout<<endl; system("pause"); }; template<class T> //函式模板實現 void swap(T &a, T &b) {     T temp;     temp = a;     a = b;     b = temp; } void showJob(const job &a) { cout<<" "<<a.name<<" = "<<a.salary; } 但是存在下列問題,我只想交換結構體中的一個成員變數,應該怎麼處理?有下列幾種方法: 1,顯式具體化 顯式具體化也是基於函式模板的,只不過在函式模板的基礎上,新增一個專門針對特定型別的、實現方式不同的具體化函式。 template<>void swap<job>(job &a, job &b) {      int salary;      salary = a.salary;      a.salary = b.salary;      b.salary = salary; } 如上所示,該具體化函式的實現與模板並不一致,編譯器解析函式呼叫時會選擇最匹配的函式定義 2,定義同名常規函式 2>定義同名常規函式 void swap(job &a, job &b) {      int salary;      salary = a.salary;      a.salary = b.salary;      b.salary = salary; } 由於編譯器在過載解析時,會選擇最匹配函式定義,所以在呼叫swap(jobA, jobB)時,編譯器會選擇void swap(job &a, job &b)函式定義,而遮蔽了模板函式。 同時,模板函式也可以過載,其操作與常規函式一致。 template <class T> void swap(T &a, T &b); template <class T> void swap(T &a, T &b, T &c); template <typename T> void swap(T &a, T &b) {     T temp;     temp = a;     a = b;     b = temp; } template <typename T> void swap(T &a, T &b, T &c) {     T temp;     temp = a;     a = b;     b = c;     c = temp; } 上面主要說的是函式模板的具體化,下面說下模板例項化。 函式模板: #define MAXNAME 128 struct job { char name[MAXNAME]: int salary; }; template<class T> void swap(T &a, T &b ) {   T temp;   temp = a;   a = b;   b = temp; }; template void swap<int>(int &a, int & b);  //顯式例項化,只需宣告 template<> void swap<job>(job &a, job &b)   //顯式具體化(上面已經講過,注意與例項化區分開,必須有定義) {   int salary:   salary = a.salary:   a.salary = b.salary;   b.salary = salary; };//explicite specialization. 類模板: template <class T> class Arrary { private:   T* ar;   int l; ... };//template class declaration. template class Array<int>;   //explicit instantiation. 顯式例項化 template<> class Array<job> { private:   job* ar;   int l; };//expicit specialization.   顯式具體化,類定義體可以不同於類模板Array 相應的,隱式例項化指的是:在使用模板之前,編譯器不生成模板的宣告和定義例項。只有當使用模板時,編譯器才根據模板定義生成相應型別的例項。如: int i=0, j=1; swap(i, j);  //編譯器根據引數i,j的型別隱式地生成swap<int>(int &a, int &b)的函式定義。 Array<int> arVal;//編譯器根據型別引數隱式地生成Array<int>類宣告和類函式定義。 顯式例項化: 當顯式例項化模板時,在使用模板之前,編譯器根據顯式例項化指定的型別生成模板例項。如前面顯示例項化(explicit instantiation)模板函式和模板類。其格式為: template typename function<typename>(argulist); template class classname<typename>; 顯式例項化只需宣告,不需要重新定義。編譯器根據模板實現例項宣告和例項定義。 顯示具體化: 對於某些特殊型別,可能不適合模板實現,需要重新定義實現,此時可以使用顯示具體化(explicite specialization)。顯示例項化需重新定義。格式為: template<> typename function<typename>(argu_list){...}; template<> class classname<typename>{...}; 綜上: template<> void swap<job>(job &a, job &b) {……};是函式模板的顯式具體化,意思是job型別不適用於函式模板swap的定義,因此通過這個顯式具體化重新定義;也可簡寫作template<> void swap(job &a, job &b); template void swap<job>(job &a, job &b);是函式模板的一個顯式例項化,只需宣告,編譯器遇到這種顯式例項化,會根據原模板的定義及該宣告直接生成一個例項函式,該函式僅接受job型。否則編譯器遇到模板的使用時才會隱式的生成相應的例項函式。