Dies ist eine Follow-up-Frage zu constexpr mit SFINAE ermitteln .
Ich möchte herausfinden, ob ein Element eines Tupels (oder irgendetwas, das mit std::get
verwendet werden kann) constexpr ist. Also habe ich die folgenden Helfer ähnlich wie Xeo geschrieben:
Jetzt mein Testfahrercode:
%Vor% Allerdings gibt dies immer false
für mich aus! Um zu überprüfen, dass aus irgendeinem Grund die falsche Überladung nicht immer aufgerufen wird, habe ich die falsche Überladung auskommentiert und den Compilerfehler erhalten:
Hinweis: Kandidatenvorlage ignoriert: Substitutionsfehler [mit N = 0, T = const std :: Tupel]: Nicht-Typ-Template-Argument ist kein konstanter Ausdruck
automatischer Check (const T & amp; arg) - & gt; sfinae_true & lt; (std :: get (arg), 0) & gt ;;
Allerdings weiß ich, dass ich std::get<N>(arg)
aufrufen und einen constexpr-Wert erhalten kann:
Das kompiliert einfach gut.
Ich habe das mit Clang 3.8.0 auf Ubuntu 16.04 getestet.
bearbeiten:
Als weiteren Test, der auf Sams Antwort basiert, habe ich das folgende Formular ausprobiert:
%Vor% Damit wird der Komma-Operator komplett entfernt, was GCC 5.4.0 gut kompiliert, aber Clang 3.8.0 klagt immer noch darüber. Interessanterweise hebt Clang hervor, dass arg
selbst kein Constexpr ist.
Warum ist das Problem immer noch? Welche Regeln gelten für die constexpr-Funktionsargumente?
Das sieht nach einem Compiler-Problem aus.
%Vor%gcc kompiliert das nicht:
t.C: 8: 61: Fehler: Template Argument 1 ist ungültig Auto Check (const T & amp; arg) - & gt; sfinae_true & lt; (std :: get (arg), N) & gt ;;
Aber nachdem ich das leicht gemacht habe, bekomme ich die erwarteten Ergebnisse mit gcc 6.1.1:
%Vor%Dies führt zu:
%Vor%Beachten Sie, dass Kommas in konstanten Ausdrücken vor C ++ 11 nicht zulässig waren. Könnte etwas von dieser Ära übrig bleiben ...