Also habe ich das auf ein minimales, vollständiges, überprüfbares Beispiel heruntergekocht und es scheint, dass Visual Studio 2015 mir einfach nicht erlaubt, eine Template-Funktion constexpr
in enable_if
zu verwenden.
Zum Beispiel:
%Vor%Gibt mir den Fehler:
Fehler C2995:
enable_if<_Test,T>::type test(void)
: Funktionsvorlage wurde bereits definiert
Wenn ich versuche, es in Substitution zu verwenden, ist der Fehler keine Kompilierung wie folgt:
%Vor% Dies funktioniert in gcc: Ссылка
Und es funktioniert gut in Visual Studio 2015, wenn ich die Templatisierung von condition
entfernen. Ich glaube, dass constexpr
Funktionen in c ++ eingeführt wurden 11 , warum unterstützt Visual Studio 2015 das nicht? Ist es ein Fehler?
Das Problem scheint zu sein, dass MSVC14 / VS2015 nicht in der Lage ist, SFINAE-Ausdrücke in Kombination mit Rückgabewerten von consExpr-Funktionen als Vorlagenparameter korrekt aufzulösen.
Um dieses Problem zu umgehen, können Sie den Rückgabewert Ihres consExpr einem 'static const' Mitglied einer Struktur zuweisen und dieses Element als Vorlagenparameter verwenden.
%Vor%Sie haben auch in den Kommentaren erwähnt, dass Ihr tatsächliches Problem in einem anderen Fall als Ihrem MCVE auftrat ( Wie kann ich ein div_t-Objekt initialisieren? )
In diesem Fall könnte die Problemumgehung wie folgt aussehen:
%Vor%Diesem Visual Studio C ++ Team Blog zu entnehmen Eintrag VS2015 hat keine (vollständige) Unterstützung für Expression SFINAE noch.
[1] Wir planen, Expression SFINAE unmittelbar nach 2015 RTM im Compiler zu implementieren, und wir planen, es in einem Update für 2015 bereitzustellen, das für den produktiven Einsatz unterstützt wird. (Aber nicht unbedingt 2015 Update 1. Es könnte länger dauern.)
Das Problem ist, dass Sie mit zwei verschiedenen Vorlagen test
des Formulars enden:
und der Compiler beschwert sich. Dies kann mit dem Ausdruck SFINAE-Fehler zusammenhängen, bei dem der Ausdruck von condition<T>()
nicht "früh genug" ausgewertet wird oder auf andere Weise fehlschlägt.
Hier ist ein Workaround:
%Vor% Jetzt unterscheiden sich die Templatesignaturen der zwei verschiedenen test
, und der Ausdruck SFINAE Auswertung von condition<T>()
funktioniert nicht richtig, verursacht kein Problem.
Dies ist ein bekanntes MSVC-Problem und wurde in einem ihrer Blogposts erwähnt. Was passiert, ist, dass der Compiler nicht erkennen kann, dass SFINAE die zweite Version von test()
anders als die erste macht, und es braucht einen kleinen Hinweis; Ein einfacher Dummy-Parameter genügt, um die beiden Versionen unterscheiden zu können.
Dieses funktioniert auf MSVC mit nur minimalen Änderungen am Code. Es ist auch leicht zu entfernen, sobald sie es ohne den Hinweis schließlich funktioniert.
Wenn eine konsistente Schnittstelle gewünscht wird, kann dies hinter einer Hilfsfunktion verborgen werden.
%Vor%Tags und Links c++ c++11 templates constexpr visual-studio-2015