std::move
| Definido en el encabezado <algorithm>
|
||
template< class InputIt, class OutputIt >
OutputIt move( InputIt first, InputIt last,
OutputIt d_first );
|
(1) | (desde C++11) (constexpr desde C++20) |
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardIt2 move( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first );
|
(2) | (desde C++17) |
[first, last), a otro rango que comienza en d_first, comenzando desde first y procediendo hasta last. Después de esta operación, los elementos en el rango de origen seguirán conteniendo valores válidos del tipo apropiado, pero no necesariamente los mismos valores que antes del movimiento.policy.true:
|
|
(hasta C++20) |
|
|
(desde C++20) |
Si d_first está dentro del rango [first, last), el comportamiento no está definido. En este caso, se puede usar std::move_backward en su lugar.
Parámetros
| first, last | - | el par de iteradores que definen el rango de origen de elementos a mover |
| d_first | - | el inicio del rango de destino |
| policy | - | la política de ejecución a utilizar |
| Requisitos de tipo | ||
-InputIt debe cumplir los requisitos de LegacyInputIterator.
| ||
-OutputIt debe cumplir los requisitos de LegacyOutputIterator.
| ||
-ForwardIt1, ForwardIt2 debe cumplir los requisitos de LegacyForwardIterator.
| ||
Valor de retorno
El iterador al elemento siguiente al último elemento movido.
Complejidad
Exactamente std::distance(first, last) asignaciones de movimiento.
Excepciones
La sobrecarga con un parámetro de plantilla llamado ExecutionPolicy reporta errores de la siguiente manera:
- Si la ejecución de una función invocada como parte del algoritmo lanza una excepción y
ExecutionPolicyes una de las políticas estándar, se llama a std::terminate. Para cualquier otroExecutionPolicy, el comportamiento está definido por la implementación. - Si el algoritmo falla al asignar memoria, se lanza std::bad_alloc.
Posible implementación
template<class InputIt, class OutputIt>
OutputIt move(InputIt first, InputIt last, OutputIt d_first)
{
for (; first != last; ++d_first, ++first)
*d_first = std::move(*first);
return d_first;
}
|
Notas
Cuando se mueven rangos superpuestos, std::move es apropiado al mover hacia la izquierda (el inicio del rango de destino está fuera del rango de origen) mientras que std::move_backward es apropiado al mover hacia la derecha (el final del rango de destino está fuera del rango de origen).
Ejemplo
El siguiente código mueve objetos thread (que en sí mismos no son copiables) de un contenedor a otro.
#include <algorithm>
#include <chrono>
#include <iostream>
#include <iterator>
#include <list>
#include <thread>
#include <vector>
void f(int n)
{
std::this_thread::sleep_for(std::chrono::seconds(n));
std::cout << "thread " << n << " ended" << std::endl;
}
int main()
{
std::vector<std::jthread> v;
v.emplace_back(f, 1);
v.emplace_back(f, 2);
v.emplace_back(f, 3);
std::list<std::jthread> l;
// copy() would not compile, because std::jthread is noncopyable
std::move(v.begin(), v.end(), std::back_inserter(l));
}
Salida:
thread 1 ended
thread 2 ended
thread 3 ended
Véase también
(C++11) |
mueve un rango de elementos a una nueva ubicación en orden inverso (plantilla de función & objeto función de algoritmo) |
(C++20) |
|
(C++11) |
convierte el argumento en un xvalue (plantilla de función) |
(C++20) |
mueve un rango de elementos a una nueva ubicación (objeto función de algoritmo) |