Partial Template Specialization
顾名思义,模版偏特化就是对模版进行特化的意思。
举个例子:
namespace SHFTest
{
template<
class PLA,
class PLB
>
class PLClass
{
//
// 一般实现
//
public:
PLClass(){};
~PLClass(){};
void FuncA()
{
}
};
typedef myPLA;
typedef myPLB;
//
// 单参数特化实现,参数A
//
template<class PLA>
class PLClass<PLA,myPLB>
{
//
// 特化实现
//
PLClass(){};
~PLClass(){};
void FuncA()
{
}
};
//
// 单参数特化实现,参数B
//
template<class PLB>
class PLClass<myPLA,PLB>
{
//
// 特化实现
//
PLClass(){};
~PLClass(){};
void FuncA()
{
}
};
//
// 双参数特化实现
//
template<>
class PLClass<myPLA,myPLB>
{
//
// 特化实现
//
PLClass(){};
~PLClass(){};
void FuncA()
{
}
};
} 第一段代码是一个普通的template class,支持两个模板参数。
假如我对于某种对象,需要做特殊化的处理,这样就要用到模版偏特化了:
例如第二段代码,第三段代码,第四段代码分别对参数A,参数B和两个参数做了偏特化。
编译器会帮你的代码自动匹配到最好的模板上面进行实例化。
这个有点类似于函数的重载,但是和重载是不一样的,根据《深入探索C++对象模型》中的描述,函数重载会在运行时发生,利用函数对象忠的vtable来实现的。而模版偏特化发生在编译期间,由编译器来自动匹配完成的。没有运行时的开销。
注意几点:
你能对已经做过偏特化的class忠的成员函数做偏特化,而你想单独对某个函数做偏特化这是不允许的。请看以下例子:
这样是被允许的:
namespace SHFTest
{
template<
class PLA,
class PLB
>
class PLClass
{
//
// 一般实现
//
public:
PLClass(){};
~PLClass(){};
void FuncA(){};
};
typedef myPLA;
typedef myPLB;
//
// 单参数特化实现,参数A
//
template<class PLA>
class PLClass<PLA,myPLB>
{
//
// 特化实现
//
PLClass(){};
~PLClass(){};
void FuncA();
};
template<class PLA>
void PLClass<PLA,myPLB>::FuncA()
{
}
} 而下面的这种情况是不允许的,编译不过的:
namespace SHFTest
{
template<
class PLA,
class PLB
>
class PLClass
{
//
// 一般实现
//
public:
PLClass(){};
~PLClass(){};
void FuncA();
};
typedef myPLA;
typedef myPLB;
template<class PLA>
void PLClass<PLA,myPLB>::FuncA()
{
}
} 当然直接偏特化namespace级别的函数也是不被允许的。你可以对这些函数做重载。这就意味着你只能更改函数的参数列表而不能改变函数的返回类型等。
请看以下代码:
template <class T, class U> T Fun(U obj);
//primary template
template <class U> void Fun<void, U>(U obj);
//illegal partial specialization
template <class T> T Fun (Window obj);
//legal (overloading) 写得不好,还请大家指正。