2015-05-20 5 views
8

Beim Schreiben meiner ersten Frage, ob das überhaupt möglich ist, bin ich über die Frage static constexpr member of same type as class being defined gestolpert, die ganz klar geantwortet hat, dass meine saubere Lösung mit C++ nicht möglich ist 11.Statische conexpr Mitglieder des gleichen Typs wie Klasse definiert (weitere Details)

Aber dann kam ich mit diesem Code auf, die auf die ursprüngliche Plakat ganz in der Nähe ist, und ich möchte erreichen:

class MyEnum 
{ 
public: 
    constexpr MyEnum() : m_null(true), m_value(0) { } 
    constexpr MyEnum(const unsigned int v) : m_null(false), m_value(v) { } 

    constexpr operator unsigned int() const { return m_value; } 

    static constexpr const MyEnum one() { return MyEnum(1); } 

private: 
    bool m_null; 
    unsigned int m_value; 
}; 

Also meine Frage ich Umformulierung: Warum die Lösung für one Kompilierung tut und kann verwendet werden, wie Sie es erwarten würden, aber die folgenden Lösungen geben Fehler bei der Verwendung einer unvollständigen Klasse?

class MyEnum 
{ 
public: 
    // snip... 

    static constexpr const MyEnum two = MyEnum(2); 
    static constexpr const MyEnum three = 3; 

    // snip... 
} 
+1

Die Körper der Elementfunktionen werden so kompiliert, als ob sie nach der Klassendefinition liegen würden. Das heißt, die Klasse ist innerhalb der Memberfunktionskörper vollständig. (Siehe auch [CWG 1255] (http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#1255)) – dyp

Antwort

9

Als @dyp die Lösung für one erwähnt kompiliert, weil Funktionsdefinitionen nach der Klasse Körper kompiliert werden. So ist es wie one hat wie diese

class MyEnum 
{ 
public: 
    static constexpr const MyEnum one(); 
    //... Definition here 
}; //Class is fully defined after here 

inline static constexpr const MyEnum MyEnum::one() { return MyEnum(1); } 
         //Fine here because class is complete ^^^^ 

Auf der anderen Seite, Definitionen in der Klasse Körper erklärt werden zusammengestellt, wie sie in der Klasse Körper platziert werden. Also, wenn two und three sind die Klasse kompiliert wird ist noch nicht vollständig definiert.