Partial Template Specialization
顧名思義,模版偏特化就是對(duì)模版進(jìn)行特化的意思。
舉個(gè)例子:
namespace?SHFTest


{
????template<
????????????class?PLA,
????????????class?PLB
????????????>
????class?PLClass

????
{
????????//
????????//?一般實(shí)現(xiàn)
????????//
????public:

????????PLClass()
{};

????????~PLClass()
{};
????????void?FuncA()

????????
{
????????}
????};

????typedef?myPLA;
????typedef?myPLB;

????//
????//?單參數(shù)特化實(shí)現(xiàn),參數(shù)A
????//
????template<class?PLA>
????class?PLClass<PLA,myPLB>

????
{
????????//
????????//?特化實(shí)現(xiàn)
????????//

????????PLClass()
{};

????????~PLClass()
{};
????????void?FuncA()

????????
{
????????}
????};

????//
????//?單參數(shù)特化實(shí)現(xiàn),參數(shù)B
????//
????template<class?PLB>
????class?PLClass<myPLA,PLB>

????
{
????????//
????????//?特化實(shí)現(xiàn)
????????//

????????PLClass()
{};

????????~PLClass()
{};
????????void?FuncA()

????????
{
????????}
????};

????//
????//?雙參數(shù)特化實(shí)現(xiàn)
????//
????template<>
????class?PLClass<myPLA,myPLB>

????
{
????????//
????????//?特化實(shí)現(xiàn)
????????//

????????PLClass()
{};

????????~PLClass()
{};
????????void?FuncA()

????????
{
????????}
????};
}?第一段代碼是一個(gè)普通的template class,支持兩個(gè)模板參數(shù)。
假如我對(duì)于某種對(duì)象,需要做特殊化的處理,這樣就要用到模版偏特化了:
例如第二段代碼,第三段代碼,第四段代碼分別對(duì)參數(shù)A,參數(shù)B和兩個(gè)參數(shù)做了偏特化。
編譯器會(huì)幫你的代碼自動(dòng)匹配到最好的模板上面進(jìn)行實(shí)例化。
這個(gè)有點(diǎn)類似于函數(shù)的重載,但是和重載是不一樣的,根據(jù)《深入探索C++對(duì)象模型》中的描述,函數(shù)重載會(huì)在運(yùn)行時(shí)發(fā)生,利用函數(shù)對(duì)象忠的vtable來(lái)實(shí)現(xiàn)的。而模版偏特化發(fā)生在編譯期間,由編譯器來(lái)自動(dòng)匹配完成的。沒(méi)有運(yùn)行時(shí)的開(kāi)銷。
注意幾點(diǎn):
你能對(duì)已經(jīng)做過(guò)偏特化的class忠的成員函數(shù)做偏特化,而你想單獨(dú)對(duì)某個(gè)函數(shù)做偏特化這是不允許的。請(qǐng)看以下例子:
這樣是被允許的:
namespace?SHFTest


{
????template<
????????????class?PLA,
????????????class?PLB
????????????>
????class?PLClass

????
{
????????//
????????//?一般實(shí)現(xiàn)
????????//
????public:

????????PLClass()
{};

????????~PLClass()
{};

????????void?FuncA()
{};
????};

????typedef?myPLA;
????typedef?myPLB;

????//
????//?單參數(shù)特化實(shí)現(xiàn),參數(shù)A
????//
????template<class?PLA>
????class?PLClass<PLA,myPLB>

????
{
????????//
????????//?特化實(shí)現(xiàn)
????????//

????????PLClass()
{};

????????~PLClass()
{};
????????void?FuncA();
????};

????template<class?PLA>
????void?PLClass<PLA,myPLB>::FuncA()

????
{

????}
}而下面的這種情況是不允許的,編譯不過(guò)的:
namespace?SHFTest


{
????template<
????????????class?PLA,
????????????class?PLB
????????????>
????class?PLClass

????
{
????????//
????????//?一般實(shí)現(xiàn)
????????//
????public:

????????PLClass()
{};

????????~PLClass()
{};
????????void?FuncA();
????};

????typedef?myPLA;
????typedef?myPLB;

????template<class?PLA>
????void?PLClass<PLA,myPLB>::FuncA()

????
{

????}
}當(dāng)然直接偏特化namespace級(jí)別的函數(shù)也是不被允許的。你可以對(duì)這些函數(shù)做重載。這就意味著你只能更改函數(shù)的參數(shù)列表而不能改變函數(shù)的返回類型等。
請(qǐng)看以下代碼:
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)寫(xiě)得不好,還請(qǐng)大家指正。