close
Espacios de nombres
Variantes

std::move_if_noexcept

De cppreference.com
 
 
Biblioteca de servicios
 
<tbody> </tbody> <tbody class="t-dcl-rev "> </tbody><tbody> </tbody>
Definido en el archivo de encabezado <utility>
template< class T > typename std::conditional< !std::is_nothrow_move_constructible<T>::value && std::is_copy_constructible<T>::value, const T&, T&& >::type move_if_noexcept(T& x) noexcept;
(desde C++11)
(hasta C++14)
template< class T > constexpr typename std::conditional< !std::is_nothrow_move_constructible<T>::value && std::is_copy_constructible<T>::value, const T&, T&& >::type move_if_noexcept(T& x) noexcept;
(desde C++14)

move_if_noexcept obtiene una referencia r-valor a su argumento si su constructor de movimiento no lanza excepciones o si no hay un constructor de copia (tipo de solo movimiento), de lo contrario obtiene una referencia l-valor a su argumento. Por lo general, se usa para combinar la semántica de movimiento con una garantía de excepción fuerte.

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.

Notas

Esto lo usa, por ejemplo, std::vector::resize, que puede tener que asignar un 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 usó std::move_if_noexcept para decidir si usaría construcción de movimiento o construcción de copia (a menos que el constructor de copia no esté disponible, en cuyo caso el constructor de movimiento se usa de cualquier manera y se puede renunciar a la garantía de excepción fuerte).

Ejemplo

#include <iostream>
#include <utility>

struct Mala
{
    Mala() {}
    Mala(Mala&&)  // puede lanzar
    {
        std::cout << "Se ha llamado al constructor de movimiento que lanza\n";
    }
    Mala(const Mala&) // también puede lanzar
    {
        std::cout << "Se ha llamado al constructor de copia que lanza\n";
    }
};

struct Buena
{
    Buena() {}
    Buena(Buena&&) noexcept // NO lanzará
    {
        std::cout << "Se ha llamado al constructor de movimiento que no lanza\n";
    }
    Buena(const Buena&) noexcept // NO lanzará
    {
        std::cout << "Se ha llamado al constructor de copia que no lanza\n";
    }
};

int main()
{
    Buena g;
    Mala b;
    Buena g2 = std::move_if_noexcept(g);
    Mala b2 = std::move_if_noexcept(b);
}

Salida:

Se ha llamado al constructor de movimiento que no lanza
Se ha llamado al constructor de copia que lanza

Complejidad

Constante

Véase también

(C++11)
Reenvía una función argumento
(plantilla de función) [editar]
(C++11)
Obtiene una referencia r-valor
(plantilla de función) [editar]