is_move_constructible is a compile-time type trait that asks whether a type can be constructed from an rvalue of that same type. It does not confirm that the type declares a move constructor. section 6.1.4
Checking an abstract type
A compile-time check can assert that Race::Blob is not move constructible. Because Blob is abstract, it cannot be constructed through copies or moves, even though it has a virtual destructor. section 6.1.4
Listing 6.10 Type traits to check for special member functions
#include <type_traits>
void check_properties()
{
... #1
static_assert(
!std::is_default_constructible_v<Race::Blob>
); #2
static_assert(
std::is_destructible_v<Race::Blob>
); #2
static_assert(
!std::is_copy_constructible_v<Race::Blob>
); #2
static_assert(
!std::is_copy_assignable_v<Race::Blob>
); #2
static_assert(
!std::is_move_constructible_v<Race::Blob>
); #2
static_assert(
!std::is_move_assignable_v<Race::Blob>
); #2
static_assert(
std::has_virtual_destructor_v<Race::Blob>
); #3
}
Compare move-constructibility with default construction, destruction, copying, and move assignment in one constexpr static_assert checklist. section 6.1.4
A type may accept an apparent move while performing a copy instead. Declaring a destructor can block implicit move operations, so the trait may reveal constructibility without proving that move optimization is available. section 6.1.4
