std::uninitialized_move
De cppreference.com
<tbody>
</tbody>
| Definido en el archivo de encabezado <memory>
|
||
template< class InputIt, class NoThrowForwardIt > NoThrowForwardIt uninitialized_move( InputIt first, InputIt last, NoThrowForwardIt d_first ); |
(1) | (desde C++17) |
template< class ExecutionPolicy, class ForwardIt, class NoThrowForwardIt > NoThrowForwardIt uninitialized_move( ExecutionPolicy&& policy, ForwardIt first, ForwardIt last, NoThrowForwardIt d_first ); |
(2) | (desde C++17) |
1) Mueve elementos del rango
[first, last) a un área de memoria no inicializada que comienza en d_first como si fuera por
for (; first != last; ++d_first, (void) ++first)
::new (/*VOIDIFICAR*/(*d_first))
typename std::iterator_traits<NoThrowForwardIt>::value_type(std::move(*first));
donde /*VOIDIFICAR*/(e) es:
|
(hasta C++20) |
|
(desde C++20) |
Si se lanza una excepción durante la inicialización, algunos objetos en
[first, last) se dejan en un estado válido pero no especificado, y los objetos ya construidos se destruyen en un orden no especificado.2) Igual que (1), pero ejecutado de acuerdo con
policy. Esta sobrecarga no participa en la resolución de sobrecarga a menos que std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> (hasta C++20) std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> (desde C++20) sea verdadera.Parámetros
| first, last | - | El rango de los elementos a mover. |
| d_first | - | El comienzo del rango de destino. |
| policy | - | La política de ejecución a usar. Véase política de ejecución para más detalles. |
| Requisitos de tipo | ||
-InputIt debe satisfacer los requisitos de InputIterator.
| ||
-ForwardIt debe satisfacer los requisitos de ForwardIterator.
| ||
-NoThrowForwardIt debe satisfacer los requisitos de ForwardIterator.
| ||
-Ningún incremento, asignación, comparación o direccionamiento indirecto a través de instancias válidas de NoThrowForwardIt puede lanzar excepciones.
| ||
Valor de retorno
Iterador al elemento más allá del último elemento movido.
Complejidad
Lineal en la distancia entre first y last.
Excepciones
La sobrecarga con un parámetro de plantilla llamado ExecutionPolicy (política de ejecución) reporta errores tales que:
- Si la ejecución de una función invocada como parte del algoritmo lanza una excepción y la política de ejecución es una de las tres políticas estándar, se llama a std::terminate. Para cualquier otra política de ejecución, 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 NoThrowForwardIt>
NoThrowForwardIt uninitialized_move(InputIt first, InputIt last, NoThrowForwardIt d_first)
{
using Value = typename std::iterator_traits<NoThrowForwardIt>::value_type;
NoThrowForwardIt current = d_first;
try {
for (; first != last; ++first, (void) ++current) {
::new (const_cast<void*>(static_cast<const volatile void*>(
std::addressof(*current)))) Value(std::move(*first));
}
return current;
} catch (...) {
std::destroy(d_first, current);
throw;
}
}
|
Ejemplo
Ejecuta este código
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <memory>
#include <string>
void print(auto rem, auto first, auto last) {
for (std::cout << rem; first != last; ++first)
std::cout << std::quoted(*first) << ' ';
std::cout << '\n';
}
int main() {
std::string in[] { "Home", "Work!" };
print("Inicialmente, in es: ", std::begin(in), std::end(in));
if (
constexpr auto sz = std::size(in);
void* out = std::aligned_alloc(alignof(std::string), sizeof(std::string) * sz)
) {
try {
auto first {static_cast<std::string*>(out)};
auto last {first + sz};
std::uninitialized_move(std::begin(in), std::end(in), first);
print("Después del movimiento, in es: ", std::begin(in), std::end(in));
print("Después del movimiento, out es: ", first, last);
std::destroy(first, last);
}
catch (...) {
std::cout << "¡Excepción!\n";
}
std::free(out);
}
}
Posible salida:
Inicialmente, in es: "Home" "Work!"
Después del movimiento, in es: "" ""
Después del movimiento, out es: "Home" "Work!"
Véase también
| Copia un rango de objetos a una zona de memoria sin inicializar. (plantilla de función) | |
(C++17) |
Mueve un número de objetos a un área de memoria sin inicializar. (niebloid) |
(C++20) |
Mueve un rango de objetos a un área de memoria sin inicializar. (niebloid) |