Code:
#include
#include
#include
#include
#include
struct value
{
~value(
std::is_move_constructible<T>
is true iff std::is_constructible<T, T&&>
is true, but that doesn't imply that such a construction will call a move constructor, only that it is possible to construct the type from an rvalue of the same type. Such a construction might use a copy constructor.
When value::s
is a unique_ptr
the type's copy constructor and copy assignment operator are defined as deleted, because the s
member is not copyable. It does not have a move constructor and move assignment operator because, as you pointed out, it has a user-declared destructor. That means it has no copy constructor and no move constructor (and no other user-defined constructors that could accept an argument of type value&&
) so std::is_constructible<value, value&&>
is false.
When value::s
is a string
the type's copy constructor and copy assignment operator are not defined as deleted, because the s
member is copyable, and so value
is also copyable, and a CopyConstructible type is also MoveConstructible, because it's valid in this context:
value v1;
value v2 = std::move(v1); // calls copy constructor
That means std::is_constructible<value, value&&>
is true, even though it invokes the copy constructor not a move constructor.