Espacios de nombres
Variantes
Acciones

std::uninitialized_copy

De cppreference.com
< cpp‎ | memory
 
 
Biblioteca de servicios
 
Gestión de memoria dinámica
Punteros inteligentes
(C++11)
(C++11)
(C++11)
(hasta C++17)
(C++11)
(C++23)
Asignadores de memoria
Recursos de memoria
Almacenamiento no inicializado
Algoritmos de memoria no inicializada
Algoritmos restringidos de memoria no inicializada
Apoyo para recolección de basura
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
(C++11)(hasta C++23)
Misceláneos
(C++20)
(C++11)
(C++11)
 
Definido en el archivo de encabezado <memory>
template< class InputIt, class NoThrowForwardIt >

NoThrowForwardIt uninitialized_copy( InputIt first, InputIt last,

                                     NoThrowForwardIt d_first );
(1)
template< class ExecutionPolicy, class ForwardIt, class NoThrowForwardIt >

NoThrowForwardIt uninitialized_copy( ExecutionPolicy&& policy,
                                     ForwardIt first, ForwardIt last,

                                     NoThrowForwardIt d_first );
(2) (desde C++17)
1) Copia 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(*first);

donde /*VOIDIFICAR*/(e) es:

static_cast<void*>(&e)
(hasta C++11)
static_cast<void*>(std::addressof(e))
(desde C++11)
(hasta C++20)
const_cast<void*>(static_cast<const volatile void*>(std::addressof(e)))
(desde C++20)
Si se lanza una excepción durante la inicialización, 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.

Contenido

[editar] Parámetros

first, last - El rango de los elementos a copiar.
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. Aplicar &* a un valor NoThrowForwardIt debe generar un puntero a su tipo valor. (hasta C++11)

[editar] Valor de retorno

Iterador al elemento más allá del último elemento copiado.

[editar] Complejidad

Lineal en la distancia entre first y last.

[editar] 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.

[editar] Posible implementación

template<class InputIt, class NoThrowForwardIt>
NoThrowForwardIt uninitialized_copy(InputIt first, InputIt last, NoThrowForwardIt d_first)
{
    using T = 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)))) T(*first);
        }
        return current;
    } catch (...) {
        for (; d_first != current; ++d_first) {
            d_first->~T();
        }
        throw;
    }
}

[editar] Ejemplo

#include <iostream>
#include <memory>
#include <cstdlib>
#include <string>
 
int main()
{
    const char *v[] = {"Este", "es", "un", "ejemplo"};
 
    auto sz = std::size(v);
 
    if(void *pbuf = std::aligned_alloc(alignof(std::string), sizeof(std::string) * sz))
    {
        try
        {
            auto first = static_cast<std::string*>(pbuf);
            auto last = std::uninitialized_copy(std::begin(v), std::end(v), first);
 
            for (auto it = first; it != last; ++it)
                std::cout << *it << '_';
            std::cout << '\n';
 
            std::destroy(first, last);
        }
        catch(...) {}
        std::free(pbuf);
    }
}

Salida:

Este_es_un_ejemplo_

[editar] Véase también

Copia un número de objetos a un área de memoria sin inicializar.
(plantilla de función) [editar]
Copia un rango de objetos a un área de memoria sin inicializar.
(niebloid) [editar]