8

While writing my initial question, if this is even possible, I stumbled about the question static constexpr member of same type as class being defined, which quite clearly answered that my clean solution is not possible with C++11.

But then I came up with this code which is quite close to the original poster and I want to achieve:

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

So I'm rephrasing my question: Why does the solution for one compile and can be used as you would expect it but the following solutions give errors about using an incomplete class?

class MyEnum
{
public:
    // snip...

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

    // snip...
}
Community
  • 1
  • 1
Hurzelchen
  • 576
  • 3
  • 16
  • 1
    The bodies of member functions are compiled as if they were located after the class definition. That is, the class is complete within the member function bodies. (See also [CWG 1255](http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#1255)) – dyp May 20 '15 at 23:06

1 Answers1

9

As @dyp mentioned the solution for one compiles because function definitions are compiled after the class body. So it is like one has been declared like this

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

On the other hand, definitions in the class body are compiled as they are placed in the class body. So when two and three are being compiled the class is not fully defined yet.

phantom
  • 3,292
  • 13
  • 21