c++ - Nested struct breaks constexpr despite being identical to global ones -


i'm having trouble 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 = get(h); // doesn't work };  constexpr coord foo::f; constexpr foo::coord2 foo::h;  int main(){} 

essentially, get(f) considered constant expression, get(h) not. thing changed 1 uses global struct coord, while other uses nested struct coord2. structs' bodies identical.

why this?


gcc error:

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

clang error:

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

it constant expression.... eventually, shows can see moving i main():

the error messages pretty clear what's going on, foo::coord2::get() isn't defined yet, because member function definitions delayed until end of enclosing class can use members declared later.

it's little surprising definition delayed until end of outermost enclosing class, you'd more surprised if foo::coord2::get() couldn't access foo::g.

the standard agrees compiler, btw. part of section 9.2p2 says

within class member-specification, class regarded complete within function bodies, default arguments, exception-specifications, , brace-or-equal-initializers non-static data members (including such things in nested classes).

unfortunately, it's inferred closing brace of class declaration becomes point-of-definition these deferred regions. believe it's defect in standard doesn't explicitly.

see also:


Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -