2015-05-20 12 views
8

Mentre scrivevo la mia domanda iniziale, se questo è anche possibile, mi sono imbattuto nella domanda static constexpr member of same type as class being defined, che ha chiaramente risposto che la mia soluzione pulita non è possibile con C++ 11.Membri statici constexpr dello stesso tipo della classe definita (dettagli aggiuntivi)

Ma poi mi si avvicinò con questo codice che è abbastanza vicino al manifesto originale e che voglio raggiungere:

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; 
}; 

Così sto riformulare la mia domanda: Perché la soluzione per one compilazione e può essere usato come ci si aspetterebbe ma le seguenti soluzioni danno errori sull'utilizzo di una classe incompleta?

class MyEnum 
{ 
public: 
    // snip... 

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

    // snip... 
} 
+1

I corpi delle funzioni membro vengono compilati come se fossero posizionati dopo la definizione della classe. Cioè, la classe è completa all'interno dei corpi delle funzioni dei membri. (Vedi anche [CWG 1255] (http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#1255)) – dyp

risposta

9

Come menzionato @dyp la soluzione per one compila perché le definizioni di funzione sono compilati dopo il corpo della classe. Quindi è come one è stato dichiarato come questo

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 ^^^^ 

D'altra parte, le definizioni del corpo della classe vengono compilati in quanto vengono inseriti nel corpo della classe. Quindi, quando vengono compilati i numeri two e three, la classe non è ancora completamente definita.