std::move_if_noexcept
| 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) |
(C++11) |
Obtiene una referencia r-valor (plantilla de función) |