2019独角兽企业重金招聘Python工程师标准>>>
类模板的特化
语义: 表明该模板类在特殊的类型下具有不同的行为.
类的定义,应该与模板类放入一个头文件中,告知编译器该特化类的存在;
类成员的定义,应该放入源文件中.该特化类就与普通类一样,是一个实实在在存在的实体.
语法: 仍依'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 */