原文轉(zhuǎn)載自:
http://www.shnenglu.com/shenhuafeng/archive/2006/12/30/17041.html
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來實(shí)現(xiàn)的。而模版偏特化發(fā)生在編譯期間,由編譯器來自動(dòng)匹配完成的。沒有運(yùn)行時(shí)的開銷。
注意幾點(diǎn):
你能對(duì)已經(jīng)做過偏特化的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()
{

}
}而下面的這種情況是不允許的,編譯不過的:
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)寫得不好,還請(qǐng)大家指正。