std::is_move_constructible,std::is_trivially_move_constructible,(3)

NAME
std::is_move_constructible,std::is_trivially_move_constructible, - std::is_move_constructible,std::is_trivially_move_constructible,

Synopsis
   Defined in header <type_traits>
   template< class T > (1) (since C++11)
   struct is_move_constructible;
   template< class T > (2) (since C++11)
   struct is_trivially_move_constructible;
   template< class T > (3) (since C++11)
   struct is_nothrow_move_constructible;
   1) If T is not a referenceable type (i.e., possibly cv-qualified void or a function
   type with a cv-qualifier-seq or a ref-qualifier), provides a member constant value
   equal to false. Otherwise, provides a member constant value equal to
   std::is_constructible<T, T&&>::value.
   2) Same as (1), but uses std::is_trivially_constructible<T, T&&>.
   3) Same as (1), but uses std::is_nothrow_constructible<T, T&&>.
   T shall be a complete type, (possibly cv-qualified) void, or an array of unknown
   bound. Otherwise, the behavior is undefined.
   If an instantiation of a template above depends, directly or indirectly, on an
   incomplete type, and that instantiation could yield a different result if that type
   were hypothetically completed, the behavior is undefined.
   The behavior of a program that adds specializations for any of the templates
   described on this page is undefined.
  Helper variable templates
   template< class T >
   inline constexpr bool is_move_constructible_v = (since C++17)
   is_move_constructible<T>::value;
   template< class T >
   inline constexpr bool is_trivially_move_constructible_v = (since C++17)
   is_trivially_move_constructible<T>::value;
   template< class T >
   inline constexpr bool is_nothrow_move_constructible_v = (since C++17)
   is_nothrow_move_constructible<T>::value; Inherited from std::integral_constant

Member constants
   value true if T is move-constructible , false otherwise
   [static] (public static member constant)

Member functions
   operator bool converts the object to bool, returns value
                 (public member function)
   operator() returns value
   (C++14) (public member function)

Member types
   Type Definition
   value_type bool
   type std::integral_constant<bool, value>

Possible implementation
  template<class T>
  struct is_move_constructible :
        std::is_constructible<T, typename std::add_rvalue_reference<T>::type> {};
  template<class T>
  struct is_trivially_move_constructible :
       std::is_trivially_constructible<T, typename std::add_rvalue_reference<T>::type> {};
  template<class T>
  struct is_nothrow_move_constructible :
       std::is_nothrow_constructible<T, typename std::add_rvalue_reference<T>::type> {};

Notes
   Types without a move constructor, but with a copy constructor that accepts const T&
   arguments, satisfy std::is_move_constructible.
   Move constructors are usually noexcept, since otherwise they are unusable in any
   code that provides strong exception guarantee.
   In many implementations, is_nothrow_move_constructible also checks if the destructor
   throws because it is effectively noexcept(T(arg)). Same applies to
   is_trivially_move_constructible, which, in these implementations, also requires that
   the destructor is trivial: GCC bug 51452, LWG issue 2116.

Example
// Run this code
 #include <iostream>
 #include <type_traits>
 struct Ex1 {
     std::string str; // member has a non-trivial but non-throwing move ctor
 };
 struct Ex2 {
     int n;
     Ex2(Ex2&&) = default; // trivial and non-throwing
 };
 struct NoMove {
     // prevents implicit declaration of default move constructor
     // however, the class is still move-constructible because its
     // copy constructor can bind to an rvalue argument
     NoMove(const NoMove&) {}
 };
 #define OUT(...) std::cout << #__VA_ARGS__ << " : " << __VA_ARGS__ << '\n'
 int main() {
     std::cout << std::boolalpha;
     OUT( std::is_move_constructible_v<Ex1> );
     OUT( std::is_trivially_move_constructible_v<Ex1> );
     OUT( std::is_nothrow_move_constructible_v<Ex1> );
     OUT( std::is_trivially_move_constructible_v<Ex2> );
     OUT( std::is_nothrow_move_constructible_v<Ex2> );
     OUT( std::is_move_constructible_v<NoMove> );
     OUT( std::is_nothrow_move_constructible_v<NoMove> );
 }

Output:
 std::is_move_constructible_v<Ex1> : true
 std::is_trivially_move_constructible_v<Ex1> : false
 std::is_nothrow_move_constructible_v<Ex1> : true
 std::is_trivially_move_constructible_v<Ex2> : true
 std::is_nothrow_move_constructible_v<Ex2> : true
 std::is_move_constructible_v<NoMove> : true
 std::is_nothrow_move_constructible_v<NoMove> : false

See also
   is_constructible
   is_trivially_constructible checks if a type has a constructor for specific
   is_nothrow_constructible arguments
   (C++11) (class template)
   (C++11)
   (C++11)
   is_default_constructible
   is_trivially_default_constructible
   is_nothrow_default_constructible checks if a type has a default constructor
   (C++11) (class template)
   (C++11)
   (C++11)
   is_copy_constructible
   is_trivially_copy_constructible
   is_nothrow_copy_constructible checks if a type has a copy constructor
   (C++11) (class template)
   (C++11)
   (C++11)
   move_constructible specifies that an object of a type can be move
   (C++20) constructed
                        (concept)
   move obtains an rvalue reference
   (C++11) (function template)
   move_if_noexcept obtains an rvalue reference if the move
   (C++11) constructor does not throw
                        (function template)