2017-01-24 13 views
1

は私が機能を処理する一般的な方法を望んでいたし、最終的にそれらを呼び出すので、私は問題以下のコードは、コードがコンパイルされていることである書いたが、私はそれをテストしたとき、私は可変引数テンプレートの特殊化の問題

種類誤ったのエラーが出ますテンプレート引数の数(1、0にする必要があります) auto al = action :: apply < 5> :: value;

私は間違っていることを知っていますが、私はそれが何であるかを知ることができませんでした。

template<typename T, typename enabled=void, typename ...P> 
struct action{ 
    template<P... args> 
    struct apply{ }; 
}; 

template<typename FN,typename ...P> 
struct action<FN, typename std::enable_if< std::is_function<FN>::value >::type ,P...>{ 
    template<P... args> 
    struct apply{ 
     static const decltype(std::result_of<FN(P...)>::type) value = FN(std::forward<P>(args)...); 
    }; 
}; 


int test(int x) 
{ 
    return x; 
} 

int main() 
{ 
    auto al= action<decltype(test), int>::apply<5>::value; 
    std::cout << "result :" << al <<std::endl; 
    return 0; 
} 

答えて

8

これはあなたの主なテンプレートです:

template<typename T, typename enabled=void, typename ...P> 
struct action 

あなたがaction<blah>を行うたびに、引数がこのプライマリテンプレートを経由して解釈されます。

action<decltype(test), int> 

はので、ここで、あなたはTとしてdecltype(test)を渡し、enabledとしてint。そして、何も...Pとして。

次に、テンプレートの特殊化が適用されているかどうかをテストします。

template<typename FN,typename ...P> 
struct action<FN, typename std::enable_if< std::is_function<FN>::value >::type ,P...> 

これは分解が必要です。 の後にactionのパターンが一致します。 の前にの部分は、それから推測する変数の一部です。

ので

action<decltype(test), int> 
struct action<FN, typename std::enable_if< std::is_function<FN>::value >::type ,P...> 

ラインにそれらをアップ:

 action<decltype(test), int> 
struct action<FN   , typename std::enable_if< std::is_function<FN>::value >::type ,P...> 

、ここでは、彼らがどのように対応するか、次のとおりです。

FN=decltype(test) 
typename std::enable_if< std::is_function<FN>::value >::type=int 
P...= 

オクラホマので、引数1は、別名int(int)decltype(test)です。これをFNと推測します。すべての良い。

次に、2つの引数があります。だから...Pは明らかに空です。

引数2は、推論されていないコンテキストです。私たちは、それを計算します:

typename std::enable_if< std::is_function<FN>::value >::type 
typename std::enable_if< std::is_function<int(int)>::value >::type 
typename std::enable_if<true>::type 
void 

...よく、この特殊化は、それがvoidであると言います。しかし、我々はintを渡した。 void=intはナンセンスなので、この専門分野は適用されません。ここでパターンマッチングに失敗しました。

したがって、私たちは、プライマリ専門に行く:

template<typename T, typename enabled=void, typename ...P> 
struct action{ 
    template<P... args> 
    struct apply{ }; 
}; 

[OK]を、ので、それは...Pが空であるためにのみ、0以外の型の引数を取り...メンバーテンプレートapplyを持っています。

あなたのエラーです。

特殊化は過負荷ではありません。これらは、プライマリテンプレートのパターンマッチング実装の置き換えです。主なテンプレートの引数は、常に署名です。スペシャライゼーションは特定の選択肢の名前を変更してパターンを一致させることができます。

おそらく別名を使用します。 actionの名前をaction_helperに変更します。オプションで、details名前空間に配置します。次に:

template<class T, class...P> 
using action = action_helper<T,void,P...>; 

クライアントコードにactionを使用します。

+0

++詳細な回答とポインタありがとうございます –

関連する問題