语义: 表明该模板类在特殊的类型下具有不同的行为.
类的定义,应该与模板类放入一个头文件中,告知编译器该特化类的存在;
类成员的定义,应该放入源文件中.该特化类就与普通类一样,是一个实实在在存在的实体.
语法: 仍依'template<>'表明该类是一个模板,但被特化的类;
类外定义特化类的成员时,不应添加'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()成员函数 */ }
语义: 表明该模板类在指定的模板实参下,其某些成员具有不同的行为.
语法: 见下面的例子.
特化成员的声明应该与模板类放在同一个头文件中.
如果成员特化后是一个实实在在的函数,则应该放入源文件中;否则应该放入头文件中.
/* 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 */