Dies ist Ihre primäre Vorlage:
template<typename T, typename enabled=void, typename ...P>
struct action
Wann immer Sie action<blah>
tun, die Argumente über diese Primärtemplats interpretiert werden.
action<decltype(test), int>
so hier, übergeben Sie decltype(test)
als T
und int
als enabled
. Und nichts als ...P
.
Wir testen dann, ob irgendwelche der Template-Spezialisierungen gelten.
template<typename FN,typename ...P>
struct action<FN, typename std::enable_if< std::is_function<FN>::value >::type ,P...>
Dies erfordert eine Untergliederung. Der Teil nachaction
ist, was wir Muster gegen übereinstimmen. Der Teil vor ist nur einige Variablen, die wir daraus ableiten.
So
action<decltype(test), int>
struct action<FN, typename std::enable_if< std::is_function<FN>::value >::type ,P...>
Linie ihnen:
action<decltype(test), int>
struct action<FN , typename std::enable_if< std::is_function<FN>::value >::type ,P...>
und hier sind, wie sie entsprechen:
FN=decltype(test)
typename std::enable_if< std::is_function<FN>::value >::type=int
P...=
Ok, also Argument 1 ist decltype(test)
, aka int(int)
. Wir folgern dies zu FN
. Alles gut.
Als nächstes gibt es 2 Argumente. So ist ...P
deutlich leer.
Argument 2 ist in einem nicht-abgeleiteten Zusammenhang. Wir werden es berechnet:
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
... na ja, diese Spezialisierung sagt es void
ist. Aber wir haben int
passiert. Da void=int
Unsinn ist, gilt diese Spezialisierung nicht. Wir haben hier keine Übereinstimmung gefunden.
So gehen wir zurück in die primäre Spezialisierung:
template<typename T, typename enabled=void, typename ...P>
struct action{
template<P... args>
struct apply{ };
};
ok, so hat es ein Mitglied Vorlage apply
, dass ... Fertig 0 nicht-Typ Argumente, weil ...P
leer.
Daher Ihr Fehler.
Spezialisierungen sind keine Überladungen. Sie sind Mustervergleichsimplementierungen der primären Vorlage. Die primären Vorlagenargumente sind immer die Signatur. Die Spezialisierung kann bestimmte Optionen umbenennen und mit Mustern vergleichen.
Sie möchten wahrscheinlich einen Alias verwenden. Benennen Sie action
in action_helper
um. Fügen Sie es optional in einen details
Namensraum ein. Dann:
template<class T, class...P>
using action = action_helper<T,void,P...>;
und verwenden Sie action
in Client-Code.
++ für die detaillierte Antwort und danke für den Zeiger –