模板特化

C++中的模板特化不同於模板的實例化,模板參數在某種特定類型下的具體實現稱為模板的特化。模板特化有時也稱之為模板的具體化,分別有函式模板特化和類模板特化。

基本介紹

  • 中文名:模板特化
  • 外文名:Template Specialization
  • 領域:計算機編程
  • 程式語言:C++
定義,函式模板特化,類模板特化,

定義

模板特化不同於模板的實例化,模板參數在某種特定類型下的具體實現稱為模板的特化。模板特化有時也稱之為模板的具體化,分別有函式模板特化和類模板特化。

函式模板特化

函式模板特化是在一個統一的函式模板不能在所有類型實例下正常工作時,需要定義類型參數在實例化為特定類型時函式模板的特定實現版本。查看如下例子。
#include <iostream>using namespace std;template<typename T> T Max(T t1,T t2){    return (t1>t2)?t1:t2;} typedef const char* CCP;template<> CCP Max<CCP>(CCP s1,CCP s2){    return (strcmp(s1,s2)>0)?s1:s2;}int main(){//調用實例:int Max<int>(int,int)    int i=Max(10,5);    //調用顯示特化:const char* Max<const char*>(const char*,const char*)    const char* p=Max<const char*>("very","good");    cout<<"i:"<<i<<endl;    cout<<"p:"<<p<<endl;}
程式正常編譯運行結果:
i:10
p:very
在函式模板顯示特化定義(Explicit Specialization Definition)中,顯示關鍵字template和一對尖括弧<>,然後是函式模板特化的定義。該定義指出了模板名、被用來特化模板的模板實參,以及函式參數表和函式體。在上面的程式中,如果不給出函式模板Max<T>在T為const char*時的特化版本,那么在比較兩個字元串的大小時,比較的是字元串的起始地址的大小,而不是字元串的內容在字典序中先後次序。
1.1.1使用函式重載替代函式模板特化
除了定義函式模板特化版本外,還可以直接給出模板函式在特定類型下的重載形式(普通函式)。使用函式重載可以實現函式模板特化的功能,也可以避免函式模板的特定實例的失效。例如,把上面的模板特化可以改成如下重載函式。
typedef const char* CCP;CCP Max(CCP s1,CCP s2){    return (strcmp(s1,s2)>0)?s1:s2;}
程式運行結果和使用函式模板特化相同。但是,使用普通函式重載和使用模板特化還是有不同之處,主要表現在如下兩個方面:
(1)如果使用普通重載函式,那么不管是否發生實際的函式調用,都會在目標檔案中生成該函式的二進制代碼。而如果使用模板的特化版本,除非發生函式調用,否則不會在目標檔案中包含特化模板函式的二進制代碼。這符合函式模板的“惰性實例化”準則。
(2)如果使用普通重載函式,那么在分離編譯模式下,應該在各個源檔案中包含重載函式的申明,否則在某些原檔案中就會使用模板實例化,而不是重載函式。

類模板特化

類模板特化類似於函式模板的特化,即類模板參數在某種特定類型下的具體實現。考察如下代碼。
#include <iostream>using namespace std; template<typename T>class A{    T num;public:    A(){        num=T(6.6);    }    void print(){        cout<<"A'num:"<<num<<endl;    }}; template<>class A<char*>{    char* str;public:    A(){        str="A' special definition ";    }    void print(){        cout<<str<<endl;    }}; int main(){    A<int> a1; //顯示模板實參的隱式實例化    a1.print();    A<char*> a2;//使用特化的類模板    A2.print();}
程式輸出結果如下:
A'num:6
A' special definition

相關詞條

熱門詞條

聯絡我們