原文轉(zhuǎn)載自:
http://www.shnenglu.com/shenhuafeng/archive/2006/12/30/17041.html
Partial Template Specialization
顧名思義,模版偏特化就是對模版進(jìn)行特化的意思。
舉個例子:
namespace SHFTest
{
template<
class PLA,
class PLB
>
class PLClass
{
//
// 一般實現(xiàn)
//
public:
PLClass(){};
~PLClass(){};
void FuncA()
{
}
};

typedef myPLA;
typedef myPLB;

//
// 單參數(shù)特化實現(xiàn),參數(shù)A
//
template<class PLA>
class PLClass<PLA,myPLB>
{
//
// 特化實現(xiàn)
//
PLClass(){};
~PLClass(){};
void FuncA()
{
}
};

//
// 單參數(shù)特化實現(xiàn),參數(shù)B
//
template<class PLB>
class PLClass<myPLA,PLB>
{
//
// 特化實現(xiàn)
//
PLClass(){};
~PLClass(){};
void FuncA()
{
}
};

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

typedef myPLA;
typedef myPLB;

//
// 單參數(shù)特化實現(xiàn),參數(shù)A
//
template<class PLA>
class PLClass<PLA,myPLB>
{
//
// 特化實現(xiàn)
//
PLClass(){};
~PLClass(){};
void FuncA();
};

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

}
}而下面的這種情況是不允許的,編譯不過的:
namespace SHFTest
{
template<
class PLA,
class PLB
>
class PLClass
{
//
// 一般實現(xiàn)
//
public:
PLClass(){};
~PLClass(){};
void FuncA();
};

typedef myPLA;
typedef myPLB;

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

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