static constexpr member of same type as class being defined

Viewed 6842

I would like a class C to have a static constexpr member of type C. Is this possible in C++11?

Attempt 1:

struct Foo {
    constexpr Foo() {}
    static constexpr Foo f = Foo();
};
constexpr Foo Foo::f;

g++ 4.7.0 says: 'invalid use of incomplete type' referring to the Foo() call.

Attempt 2:

struct Foo {
    constexpr Foo() {}
    static constexpr Foo f;
};
constexpr Foo Foo::f = Foo();

Now the problem is the lack of an initializer for the constexpr member f inside the class definition.

Attempt 3:

struct Foo {
    constexpr Foo() {}
    static const Foo f;
};
constexpr Foo Foo::f = Foo();

Now g++ complains about a redeclaration of Foo::f differing in constexpr.

4 Answers

Earlier I had the same problem and came across this decade-old question. I'm happy to report that in the intervening years a solution has appeared; we just need to do something like "attempt 3" above, but mark the definition of Foo::f as inline. Minimal example which compiles with g++ --std=c++17:

foo.hpp

#ifndef __FOO_HPP
#define __FOO_HPP

struct Foo
{
    constexpr Foo() {}
    static const Foo f;
};

inline constexpr Foo Foo::f = Foo();

#endif

foo.cpp

#include "foo.h"

main.cpp

#include "foo.h"

int main(int, char **) { return 0; }
Related