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.

Reply via email to