https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94644
Daniel Krügler <daniel.kruegler at googlemail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |daniel.kruegler@googlemail.
| |com
--- Comment #1 from Daniel Krügler <daniel.kruegler at googlemail dot com> ---
First: The issue is unrelated to the "nothrow" part of the trait. The whole
discussion can be reduced by considering the std::is_move_constructible trait
alone, because it is the one that is causing the violations of your
expectations.
Now, is_move_constructible is just a special case of is_constructible:
"For a referenceable type T, the same result as is_constructible_v<T, T&&>,
otherwise false."
Let's now look at is_constructible (I'm omitting the part of the definition
that is unrelated to object types):
<<
The predicate condition for a template specialization is_constructible<T,
Args...> shall be satisfied if and only if the following variable definition
would be well-formed for some invented variable t:
T t(declval<Args>()...);
[Note: These tokens are never interpreted as a function declaration. —end note]
>>
Now consider that your would try to write this variable definition with your
type future_state_base (which has a protected destructor): It would be
ill-formed, because for the variable definition you need a publicly accessible
destructor. Therefore std::is_move_constructible<future_state_base>::value
should be false as well as
std::is_nothrow_move_constructible<future_state_base>::value.
That's the reason why the first
static_assert(std::is_nothrow_move_constructible<future_state_base>::value,
"future_state_base's move constructor must not throw");
is required to fail (That is when foo is defined), because
static_assert(std::is_move_constructible<future_state_base>::value,
"future_state_base doesn't meet is_move_constructible");
is required to fail.
The actual error in gcc seems to me the behaviour, when foo is not defined and
when your second assertion (which is wrong) holds. This looks like a gcc error
indeed and I think that clang is just right.