これはあなたの主なテンプレートです:
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
を使用します。
++詳細な回答とポインタありがとうございます –