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
Post a Comment