語義: 代表該模板類在特殊的類型下具備不一樣的行爲.函數
類的定義,應該與模板類放入一個頭文件中,告知編譯器該特化類的存在;spa
類成員的定義,應該放入源文件中.該特化類就與普通類同樣,是一個實實在在存在的實體.code
語法: 仍依'template<>'代表該類是一個模板,但被特化的類;get
類外定義特化類的成員時,不該添加'template<>'標記.編譯器
template<> class 類名<特化類的模板實參表>{ /* 特化類的定義 */ };
對特化類的要求: 類名與模板類一致便可,其他沒有任何限制:特化類能夠具備不一樣的成員集合,特化類能夠具備不一樣的父類....編譯
template<typename Type1,typename Type2> class X{ public: void print(){ Println("模板類: Type1: %s\tType2: %s",getTypeName(Type1),getTypeName(Type2)); } }; template<> class X<int,double>{ public: void print(); void test(){} }; /* 不要添加'template<>'標記 */ void X<int,double>::print(){ Println("特化類: Type1: int\tType2: double"); } int main(int argc,char *argv[]){ X<double,double> dd; dd.print(); // dd.test(); /* 錯誤!X<double,double>不存在test()成員函數. */ X<int,double> id; id.print(); id.test(); /* 只要X<int,double>中才存在test()成員函數 */ }
語義: 代表該模板類在指定的模板實參下,其某些成員具備不一樣的行爲.模板
語法: 見下面的例子. class
特化成員的聲明應該與模板類放在同一個頭文件中.test
若是成員特化後是一個實實在在的函數,則應該放入源文件中;不然應該放入頭文件中.語法
/* TestTem.h --- 模板類及其布特化成員的聲明 */ #define getTypeName(type) typeid(type).name() #define PrintType(type) Println(#type ": %s",getTypeName(type)); template<typename Type1> struct TestTem { template<typename Type2> void func2(); void func1(); }; /* 成員func1的特化聲明.此時func1是一個實實在在的函數 */ template<> void TestTem<float>::func1(); /* 模板成員func2的特化聲明,此時僅特化了一部分.因此特化後的func2還是模板. */ template<> template<typename Type2> void TestTem<float>::func2(); /* 模板成員 func2 的特化聲明,此時進行了所有特化,func2也是一個實實在在的函數. */ template<> template<> void TestTem<float>::func2<double>(); /* --- TestTem成員定義 ---- */ template<typename Type1> void TestTem<Type1>::func1(){ Println("模板: %s",getTypeName(Type1)); } template<typename Type1> template<typename Type2> void TestTem<Type1>::func2(){ Println("模板: %s\t%s",getTypeName(Type1),getTypeName(Type2)); } /* --- 特化函數func2的定義 --- */ template<> template<typename Type2> void TestTem<float>::func2(){ Println("1特化: double\t%s",getTypeName(Type2)); } /* TestTem.cc --- 特化成員的定義 */ /* 成員func1的特化聲明.此時func1是一個實實在在的函數 */ template<> void TestTem<float>::func1(){ Println("特化: int"); } /* 模板成員 func2 的特化聲明,此時進行了所有特化,func2也是一個實實在在的函數. */ template<> template<> void TestTem<float>::func2<double>(){ Println("2特化: float\tdouble"); }
部分特化的類仍然是模板,能夠與其特化類具備徹底不一樣的成員集合,父類..
#define TypeName(type) typeid(type).name() #define PrintType(type) Println(#type ": %s",TypeName(type)); template<typename Type1,typename Type2,typename Type3> struct X{ void print(){ Println("模板: %s\t%s\t%s",TypeName(Type1),TypeName(Type2),TypeName(Type3)); } }; /* 是其模板類模板形參表的子集 */ template<typename Type2> struct X<int,Type2,double>{/* 此時 Type1=int,Type3=double */ void print(){ Println("特化: i\t%s\td",TypeName(Type2)); } }; X<double,double,double> x; /* 使用模板類,此時 Type1=Type2=Type3=double */ X<int,double,double> x1 /* 使用部分特化類,此時 Type1=int,Type2=double,Type3=double */