Warum kann ich in Visual Studio nicht eine Templatised, conexpr Funktion in enable_if verwenden?

8

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 , warum unterstützt Visual Studio 2015 das nicht? Ist es ein Fehler?

    
Jonathan Mee 11.01.2017, 14:36
quelle

4 Antworten

6

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.)

    
Simon Kraemer 11.01.2017, 17:31
quelle
3

Das Problem ist, dass Sie mit zwei verschiedenen Vorlagen test des Formulars enden:

%Vor%

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.

    
Yakk 11.01.2017 16:58
quelle
2

Eine weitere Möglichkeit zu @ Yakks Antwort:

%Vor%

EDIT: Habe gerade gesehen, dass dies im Grunde die Lösung ist, auf die TC in den Kommentaren hingewiesen hat.

EDIT2: korrigierter Code zum Kompilieren in MSVC2015, siehe Kommentare.

    
davidhigh 11.01.2017 17:07
quelle
1

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.

%Vor%

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%     
Justin Time 11.01.2017 18:04
quelle