2016-04-08 4 views
5

für diesen Code:constexpr nicht statische Elementfunktion mit nicht-constexpr Konstruktor (gcc, Klirren unterscheiden)

struct S 
{ 
    S(int m): m(m) {} 
    constexpr int f() const { return m; } 

    int m; 
}; 

int main() { S s(1); } 

es keine Warnungen oder Fehler durch clang 3.6, 3.7 und 3.8 mit -std=c++14 kompiliert wird. Aber in g ++ 5.x treten die folgenden Fehler auf:

main.cpp:4:19: error: enclosing class of constexpr non-static member function 'int S::f() const' is not a literal type 
    constexpr int f() const { return m; } 
      ^
main.cpp:1:8: note: 'S' is not literal because: 
struct S 
     ^
main.cpp:1:8: note: 'S' is not an aggregate, does not have a trivial default constructor, and has no constexpr constructor that is not a copy or move constructor 

Welcher Compiler ist richtig und warum?

Ich schaute auf die Anforderungen in C++ 14 [dcl.constexpr]/3, die besagt, dass für eine constexpr Funktion "jeder seiner Parametertypen ein Literaltyp sein soll", aber dieser Abschnitt erwähnt nicht explizit Elementfunktionen und sagt nicht, ob die implizierten *this als Parameter für die Zwecke dieser Klausel zählt.

+0

Ich bezweifle, dass eine solche Member-Funktion tatsächlich nützlich sein könnte, weil es definitiv nicht in Kompilierzeit berechnet werden kann, nicht wahr? Also würde ich sagen, GCC-Diagnose ist richtiger. – user3159253

+0

Um sicherzustellen, dass ich gerade einen Stamm GCC-Build ausprobiert habe und es immer noch kaputt ist. – user657267

+0

@ user657267 OK. Vielleicht ist es keine hohe Priorität; Wie Benutzer3159253 hervorhebt, ist dieser Code nicht sehr nützlich, weil die Auswertung von 'f()' tatsächlich nicht-consExpr ist, sogar in clang, weil 'S' kein literaler Typ ist (also 'constexpr S s (1); 'ist nicht erlaubt). –

Antwort

6

Es ist ein Kern Defekt, der für C++ 14

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1684

Clang gepatcht wurde

https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/6jM8M8FUs30

Es gibt einen Tracker für GCC festgelegt wurde, aber es wie jemand sieht nicht hat es noch angesprochen

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66297

+0

Wird dies nicht nur auf _static_ member-Funktionen angewendet? – user3159253

+0

Die Kommentare zum DR deuten darauf hin, dass das vorherige Verhalten für nicht statische Member gedacht war und diese Änderung das statische Member fixieren sollte ... aber die tatsächliche Änderung scheint für beide zu gelten. Die Handlung verdichtet sich? –

+0

In der Tat erklärt der Mailinglisten-Link, dass der Ausschuss entschied, es absichtlich für nicht-statische zu entfernen, in einer Änderung von dem, was der DR ursprünglich empfohlen –