Es scheint, dass ein Pack-Argument nur anstelle eines Pack-Parameters einer Alias-Vorlage erweitert werden kann. Dies gilt nicht für eine Klasse oder eine Funktionsvorlage:Pack-Erweiterung für Alias-Vorlage
template <class T, class... Args> struct x { using type = T; };
template <class T, class... Args> using x_t = typename x<T, Args...>::type;
template <class... Args> using x_fix_t = typename x<Args...>::type;
template <class... Args> auto f(Args...) -> void {
typename x<Args...>::type v1; // OK
x_t<Args...> v2; // Error
x_fix_t<Args...> v3; // OK
}
einfacher Fall:
template <class T, class U> using y_t = T;
template <class... Args> auto f(Args...) -> void {
y_t<Args...> v4; // Error
}
Der obige Code erzeugt Fehler mit beiden (auch wenn f
nie instanziiert) c++11
und c++14
in g++ 4.9
, g++ 5.1
und clang 3.5
.
Warum ist das nicht erlaubt und was ist die allgemeine Regel? Ich sehe keinen Grund, dies zu beschränken. Es scheint ein sehr seltsames Verbot zu sein.
Warum nicht als x_fix_t
mit der ersten Variante schreiben, ist es klarer, dass x_t
ein obligatorisches erstes Argument hat. (Zum Beispiel ist das der Grund, dass f()
nicht erlaubt ist). Aber das ist nicht so wichtig, die Lösung ist einfach. Die Frage bleibt: Warum?
gcc Fehler:
error: pack expansion argument for non-pack parameter ‘T’ of
alias template ‘template<class T, class ... Args> using x_t = typename x::type’
Klirren Fehler:
error: pack expansion used as argument for non-pack parameter of
alias template x_t<Args...> v2;
Die Info hier ist relevant, ich denke: http://Stackoverflow.com/q/24433658/4326278 – bogdan
Auch, was es wert ist, kompilieren MSVC 12 und 14 RC dies ohne Diagnose (abgesehen von normalen Warnungen für nicht referenziert Variablen) - "Implementierungsvarianz", wie sie sagen. – bogdan
Works OK in g ++ 4.8.2. –