I'm having trouble with the following code:

template<typename T>
constexpr int get(T vec) {
  return vec.get();
}

struct coord {
  constexpr int get() const { return x; }
  int x;
};

struct foo {
    struct coord2 {
      constexpr int get() const { return x; }
      int x;
    };
    constexpr static coord f = { 5 };
    constexpr static int g = get(f); // works

    constexpr static coord2 h = { 5 };
    constexpr static int i = get(h); // doesn't work
};

constexpr coord foo::f;
constexpr foo::coord2 foo::h;

int main(){}

Essentially, get(f) is considered a constant expression, but get(h) is not. The only thing changed is that one uses a global struct coord, while the other uses a nested struct coord2. The structs' bodies are identical.

Why is this?


GCC error:

test.cpp:20:35: error: field initializer is not constant

Clang error:

test.cpp:20:26: error: constexpr variable 'i' must be initialized by a constant expression
    constexpr static int i = get(h); // doesn't work
                         ^   ~~~~~~
test.cpp:8:10: note: undefined function 'get' cannot be used in a constant expression
  return vec.get();
         ^
test.cpp:20:30: note: in call to 'get({5})'
    constexpr static int i = get(h); // doesn't work
                             ^
test.cpp:13:21: note: declared here
      constexpr int get() const { return x; }
Edit
Report