1

我有這個函數應該遞歸地工作。variadic模板函數的部分專精

template <class C, typename ...Arguments> 
void addStyleClassRecursive(C *c, Arguments... arg) 
{   
    c->addStyleClass(arg...); 
    for (unsigned int i=0; i<c->children().size(); ++i) 
    { 
     addStyleClassRecursive(c->children()[i], arg...); 
    }  
} 

現在它發生在某些時候,我打這已經不是addStyleClass成員函數的類(Wt::WObject),所以編譯器會抱怨-rightly-這個問題。 好的。所以我想專門的代碼,添加一個版本Wt::WObject

template <class C=Wt::WObject, typename ...Arguments> 
void addStyleClassRecursive(Wt::WObject *c, Arguments... arg) 
{ 
    for (unsigned int i=0; i<c->children().size(); ++i) 
    { 
     addStyleClassRecursive(c->children()[i], arg...); 
    } 
} 

這本身並沒有給出一個編譯器錯誤,但它完全忽略(實際上編譯器不斷抱怨WObject不具有所要求的成員函數,指向通用函數中的同一行)。

於是,我就專門就這樣

template <typename ...Arguments> 
void addStyleClassRecursive<Wt::WObject, Arguments...>(Wt::WObject *c, Arguments... arg) 
{ 
    for (unsigned int i=0; i<c->children().size(); ++i) 
    { 
     addStyleClassRecursive(c->children()[i], arg...); 
    } 
} 

現在,編譯器會抱怨

non-type partial specialization 'addStyleClassRecursive<Wt::WObject, Arguments ...>' is not allowed 
void addStyleClassRecursive<Wt::WObject, Arguments...>(Wt::WObject *c, Arguments... arg); 
                         ^

因此,誰能指出如何達到所要求的結果呢?

回答

2

你可以做這樣的事情:

template <class C, typename ...Arguments> 
auto addStyleClassRecursiveImpl(int, C *c, Arguments... arg) 
-> decltype(c->addStyleClass(arg...), void()) { 
    c->addStyleClass(arg...); 
    // ... C has addStyleClass 
} 

template <class C, typename ...Arguments> 
void addStyleClassRecursiveImpl(char, C *c, Arguments... arg) { 
    // ... C has not addStyleClass 
} 

template <typename... T> 
void addStyleClassRecursive(T ...&&t) { 
    addStyleClassRecursiveImpl(0, std::forward<T>(t)...); 
    // ... 
} 

的想法是標籤調度請求的內部實現(在本例中稱爲addStyleClassRecursiveImpl),並使用SFINAE和函數重載挑正確的版本。


當然,你不能部分地專門化一個函數模板。

+0

我不得不做一些小改動才能使它工作,但實際上這是一個即插即用的解決方案。謝謝。 – DrHell

+1

@DHHell我是用手機寫的,所以請原諒我,如果有一些錯別字。我很高興它適合你。 – skypjack

+1

對不起,我不想聽起來傲慢或什麼,我解釋說,它需要一些小的變化,以防將來有人想使用它,並想知道爲什麼它在第一次運行時不起作用。再次感謝。 :) – DrHell

2

你不能部分地專門化一個函數模板。

你可以做的就是讓遞歸模板在其第一個可變參數模板arg上調用一個不同的函數,然後遞歸地調用它自己的剩餘參數。然後你可以完全專門的幫助功能。