Consider the following code:
#include <type_traits>
struct outer {
struct inner {
unsigned int x = 0;
};
// static_assert(std::is_default_constructible<inner>::value,
// "not default ctorable - inside");
};
static_assert(std::is_default_constructible<outer::inner>::value,
"not default ctorable - outside");
This compiles fine. But - if I uncomment the static assert inside outer - both asserts fail with clang++ and gcc++. Why should they not both pass?
Notes:
The
innerclass is, in fact, complete, at the point of the first static assertion. The assertion does not fail due to incompleteness (a failure which produces a specific error message about incompleteness).Unlike in the related Why is my class non default-constructible? , here - there are no templates, so there is no instantiation-before- the-definition.
If you remove the initializer of
xand enable the assertions, the code compiles. (This is also unlike the related question.)This:
#include <type_traits> struct outer { struct inner { unsigned int x = 0; }; inner get_an_inner() { static_assert(std::is_default_constructible<outer::inner>::value, "not default ctorable - outside"); return inner{}; } };compiles!
If we add an explicit default constructor,
constexpr inner() {}- the program compiles.There's a LLVM bug report about basically the same thing, but it's not just clang and the bug report has not gotten any comments.
Updates:
- Have submitted GCC bug 102199 (against libstdc++).
- Have commented on the LLVM bug, let's see what happens there.