Namespaces
Variants

std::move_if_noexcept

De es.cppreference.net
 
 
Biblioteca de utilidades
Soporte del lenguaje
Soporte de tipos (tipos básicos, RTTI)
Macros de prueba de características de la biblioteca (C++20)
Utilidades de programa
Funciones variádicas
Soporte de corrutinas (C++20)
Soporte de contratos (C++26)
Comparación de tres vías
(C++20)
(C++20)(C++20)(C++20)    
(C++20)(C++20)(C++20)

Utilidades generales
Operadores relacionales (obsoleto en C++20)
 
Definido en el encabezado <utility>
template< class T >
/* see below */ move_if_noexcept( T& x ) noexcept;
(desde C++11)
(constexpr desde C++14)

std::move_if_noexcept obtiene una referencia rvalue a su argumento si su constructor de movimiento no lanza excepciones o si no hay un constructor de copia (tipo solo de movimiento); de lo contrario, obtiene una referencia lvalue a su argumento. Se usa típicamente para combinar semántica de movimiento con una garantía de excepción fuerte.

El tipo de retorno de std::move_if_noexcept es:

  • T&& si std::is_nothrow_move_constructible<T>::value || !std::is_copy_constructible<T>::value es true.
  • De lo contrario, const T&.

Parámetros

x - el objeto a ser movido o copiado

Valor de retorno

std :: move ( x ) o x , dependiendo de las garantías de excepción.

Complejidad

Constante.

Notas

Esto se utiliza, por ejemplo, por std::vector::resize , que puede tener que asignar nuevo almacenamiento y luego mover o copiar elementos del almacenamiento antiguo al nuevo. Si ocurre una excepción durante esta operación, std::vector::resize deshace todo lo que hizo hasta este punto, lo cual solo es posible si se utilizó std::move_if_noexcept para decidir si usar construcción por movimiento o construcción por copia (a menos que el constructor de copia no esté disponible, en cuyo caso se usa el constructor de movimiento de todas formas y la garantía fuerte de excepción puede ser suspendida).

Ejemplo

#include <iostream>
#include <utility>
struct Bad
{
    Bad() {}
    Bad(Bad&&) // puede lanzar excepción
    {
        std::cout << "Throwing move constructor called\n";
    }
    Bad(const Bad&) // también puede lanzar excepción
    {
        std::cout << "Throwing copy constructor called\n";
    }
};
struct Good
{
    Good() {}
    Good(Good&&) noexcept // NO lanzará excepción
    {
        std::cout << "Non-throwing move constructor called\n";
    }
    Good(const Good&) noexcept // NO lanzará excepción
    {
        std::cout << "Non-throwing copy constructor called\n";
    }
};
int main()
{
    Good g;
    Bad b;
    [[maybe_unused]] Good g2 = std::move_if_noexcept(g);
    [[maybe_unused]] Bad b2 = std::move_if_noexcept(b);
}

Salida:

Non-throwing move constructor called
Throwing copy constructor called

Véase también

(C++11)
reenvía un argumento de función y utiliza el argumento de plantilla de tipo para preservar su categoría de valor
(plantilla de función)
(C++11)
convierte el argumento a un xvalue
(plantilla de función)