Namespaces
Variants

std:: is_move_constructible, std:: is_trivially_move_constructible, std:: is_nothrow_move_constructible

From cppreference.net
Metaprogramming library
Type traits
Type categories
(C++11)
(C++11) ( DR* )
Type properties
(C++11)
(C++11)
(C++14)
(C++11) (deprecated in C++26)
(C++11) ( until C++20* )
(C++11) (deprecated in C++20)
(C++11)
Type trait constants
Metafunctions
(C++17)
Supported operations
Relationships and property queries
Type modifications
Type transformations
(C++11) (deprecated in C++23)
(C++11) (deprecated in C++23)
(C++11)
(C++11) ( until C++20* ) (C++17)

Compile-time rational arithmetic
Compile-time integer sequences
Definido en el encabezado <type_traits>
template < class T >
struct is_move_constructible ;
(1) (desde C++11)
template < class T >
struct is_trivially_move_constructible ;
(2) (desde C++11)
template < class T >
struct is_nothrow_move_constructible ;
(3) (desde C++11)
Rasgo de tipo El valor de la constante miembro value
T es un tipo referenciable T no es un tipo referenciable
(1) std:: is_constructible < T, T && > :: value false
(2) std:: is_trivially_constructible < T, T && > :: value
(3) std:: is_nothrow_constructible < T, T && > :: value

Si T no es un tipo completo, (posiblemente calificado cv) void , o un array de límite desconocido, el comportamiento es indefinido.

Si una instanciación de una plantilla anterior depende, directa o indirectamente, de un tipo incompleto, y esa instanciación podría producir un resultado diferente si ese tipo se completara hipotéticamente, el comportamiento no está definido.

Si el programa añade especializaciones para cualquiera de las plantillas descritas en esta página, el comportamiento es indefinido.

Contenidos

Plantillas de variables auxiliares

template < class T >

inline constexpr bool is_move_constructible_v =

is_move_constructible < T > :: value ;
(desde C++17)
template < class T >

inline constexpr bool is_trivially_move_constructible_v =

is_trivially_move_constructible < T > :: value ;
(desde C++17)
template < class T >

inline constexpr bool is_nothrow_move_constructible_v =

is_nothrow_move_constructible < T > :: value ;
(desde C++17)

Heredado de std:: integral_constant

Constantes miembro

value
[static]
true si T es move-constructible, false en caso contrario
(constante miembro pública estática)

Funciones miembro

operator bool
convierte el objeto a bool , devuelve value
(función miembro pública)
operator()
(C++14)
devuelve value
(función miembro pública)

Tipos miembro

Tipo Definición
value_type bool
type std:: integral_constant < bool , value >

Implementación posible

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> {};

Notas

Los tipos sin un constructor de movimiento, pero con un constructor de copia que acepta const T & argumentos, satisfacen std::is_move_constructible .

Los constructores de movimiento suelen ser noexcept, ya que de lo contrario no se pueden utilizar en ningún código que proporcione una garantía de excepción fuerte.

En muchas implementaciones, std::is_nothrow_move_constructible también verifica si el destructor lanza excepciones porque es efectivamente noexcept ( T ( arg ) ) . Lo mismo aplica para std::is_trivially_move_constructible , que, en estas implementaciones, también requiere que el destructor sea trivial: GCC bug 51452 , LWG issue 2116 .

Ejemplo

#include <string>
#include <type_traits>
struct Ex1
{
    std::string str; // el miembro tiene un constructor de movimiento no trivial pero no lanzador de excepciones
};
static_assert(std::is_move_constructible_v<Ex1>);
static_assert(!std::is_trivially_move_constructible_v<Ex1>);
static_assert(std::is_nothrow_move_constructible_v<Ex1>);
struct Ex2
{
    int n;
    Ex2(Ex2&&) = default; // trivial y no lanzador de excepciones
};
static_assert(std::is_move_constructible_v<Ex2>);
static_assert(std::is_trivially_move_constructible_v<Ex2>);
static_assert(std::is_nothrow_move_constructible_v<Ex2>);
struct NoMove1
{
    // previene la declaración implícita del constructor de movimiento por defecto;
    // sin embargo, la clase sigue siendo construible por movimiento porque su
    // constructor de copia puede enlazar con un argumento de valor R
    NoMove1(const NoMove1&) {}
};
static_assert(std::is_move_constructible_v<NoMove1>);
static_assert(!std::is_trivially_move_constructible_v<NoMove1>);
static_assert(!std::is_nothrow_move_constructible_v<NoMove1>);
struct NoMove2
{
    // No es construible por movimiento ya que la referencia de valor L
    // no puede enlazar con el argumento de valor R
    NoMove2(NoMove2&) {}
};
static_assert(!std::is_move_constructible_v<NoMove2>);
static_assert(!std::is_trivially_move_constructible_v<NoMove2>);
static_assert(!std::is_nothrow_move_constructible_v<NoMove2>);
int main() {}

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 2196 C++11 el comportamiento no estaba claro si T && no puede formarse el valor producido es false en este caso

Véase también

verifica si un tipo tiene un constructor para argumentos específicos
(plantilla de clase)
verifica si un tipo tiene un constructor por defecto
(plantilla de clase)
verifica si un tipo tiene un constructor de copia
(plantilla de clase)
especifica que un objeto de un tipo puede ser construido por movimiento
(concepto)
(C++11)
convierte el argumento a un xvalue
(plantilla de función)
convierte el argumento a un xvalue si el constructor de movimiento no lanza excepciones
(plantilla de función)