1

私は再帰的に動作するはずのこの関数を持っています。バリデーションテンプレート関数の部分的な特殊化

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

@DrHell携帯電話から書きましたので、いくつかのタイプミスがあったら私を許してください。私はそれがあなたのためにうれしいです。 – skypjack

+1

申し訳ありませんが、私は傲慢に聞こえませんでした、何か、将来の誰かがそれを使いたがっていて、最初の動作でうまくいかなかったのかどうか疑問に思っていただけです。再度、感謝します。 :) – DrHell

2

機能テンプレートを部分的に特殊化することはできません。

あなたができることは、再帰的テンプレートが最初のバリデーショナルテンプレートargで別の関数を呼び出し、残りの引数で再帰的に自身を呼び出しさせることです。その後、ヘルパー機能を完全に専門にすることができます。

関連する問題