工作中遇到一個(gè)問題,我有一個(gè)容器,裝著各式各樣的對(duì)象的指針,需要把擁有dump方法的指針內(nèi)容dump出去,而對(duì)于沒有dump方法的對(duì)象,直接忽略。
首先想到的是給每個(gè)對(duì)象提供一個(gè)查詢操作,從而得知是否擁有dump方法。顯然這個(gè)方法不能讓人滿意,需要更改大量的class實(shí)現(xiàn)。C++如果我能自動(dòng)判斷某個(gè)類型是否擁有某方法,這個(gè)問題可以完美的解決,因?yàn)槭欠窈心撤椒ň幾g期已經(jīng)確定了,所以是有可能通過一些技巧來實(shí)現(xiàn)這個(gè)功能的。
查閱了大量的模板偏特化,匹配失敗不是錯(cuò)誤,終于找到了Mr.Right:
廢話不多說,貼代碼:
檢測(cè)是否有定義
void hello():
點(diǎn)擊(此處)折疊或打開
template<typename T>
struct has_hello{
template<typename U,
void (U::*)()>
struct HELPS;
template<typename U>
static char Test(HELPS<U, &U::hello>*);
template<typename U>
static int Test(

);
const static bool Has =
sizeof(Test<T>(0)) ==
sizeof(
char);
}
測(cè)試:
點(diǎn)擊(此處)折疊或打開
struct A
{
void hello(){
cout<<"A is Hello."<<endl;
}
int x;
};
int main()
{
cout<<"A has hello? "<<has_hello<A>::Has<<endl;
}
has_hello 能編譯通過,而且能工作!?。?br />
解釋:
template<typename U>
static int Test(

); 能匹配所有的類型U
template<typename U,
void (U::*)()>
struct HELPS; 當(dāng)Type U有hello,且hello的類型為
void (U::*)()時(shí),模板HELPS<U, &U::hello>能正確匹配,否則模板無法匹配
Test<T>(0) 優(yōu)先匹配 HELPS<U, &U::hello> 因?yàn)閠emplate<typename U>
static char Test(HELPS<U, &U::hello>*) 是一個(gè)特化
sizeof操作符不需要計(jì)算表達(dá)式的值,是一個(gè)編譯期的操作,定義指針類型可以只有聲明沒有定義
所以HELPS和Test都不需要實(shí)現(xiàn),僅有聲明就可以通過編譯
巧妙的探測(cè)了自定義類型A是否含有void U::hello() 方法。
轉(zhuǎn)自:http:
//blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=17286628&id=4643663