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)寫得不好,還請大家指正。