Espacios de nombres
Variantes

std::ranges::uninitialized_copy, std::ranges::uninitialized_copy_result

De cppreference.com
 
 
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)
 
<tbody> </tbody>
Definido en el archivo de encabezado <memory>
Signatura de la llamada
template< std::input_iterator I, std::sentinel_for<I> S1, no-throw-forward-iterator O, no-throw-sentinel-for<O> S2 > requires std::constructible_from<std::iter_value_t<O>, std::iter_reference_t<I>> uninitialized_copy_result<I, O> uninitialized_copy( I ifirst, S1 ilast, O ofirst, S2 olast );
(1) (desde C++20)
template< ranges::input_range IR, no-throw-forward-range OR > requires std::constructible_from<ranges::range_value_t<OR>, ranges::range_reference_t<IR>> uninitialized_copy_result<ranges::borrowed_iterator_t<IR>, ranges::borrowed_iterator_t<OR>> uninitialized_copy( IR&& in_range, OR&& out_range );
(2) (desde C++20)
Tipos auxiliares
template<class I, class O> using uninitialized_copy_result = ranges::in_out_result<I, O>;
(3) (desde C++20)
1) Sea N ranges::min(ranges::distance(ifirst, ilast), ranges::distance(ofirst, olast)), construye N elementos en el rango de salida [ofirst, olast), que es un área de memoria no inicializada, de los elementos en el rango de entrada [ifirst, ilast).
Los rangos de entrada y salida no deben superponerse.
Si se lanza una excepción durante la inicialización, los objetos ya construidos se destruyen en un orden no especificado.
La función tiene el efecto igual a:
for (; !(ifirst == ilast || ofirst == olast); ++ofirst, ++ifirst) {
    ::new (const_cast<void*>(static_cast<const volatile void*>(std::addressof(*ofirst))))
        std::remove_reference_t<std::iter_reference_t<O>>(*ifirst);
}
2) Igual que (1), pero usa in_range como primer rango y out_range como segundo rango, como si usara ranges::begin(in_range) como ifirst, ranges::end(in_range) como ilast, ranges::begin(out_range) como ofirst, y ranges::end(out_range) como olast.

Las entidades similares a funciones descritas en esta página son niebloids, es decir:

En la práctica, pueden implementarse como objetos función o con extensiones de compilador especiales.

Parámetros

ifirst, ilast - Par iterador-centinela que denota el rango de elementos del que copiar.
in_range - El rango de elementos del que copiar.
ofirst, olast - Iterador-centinela que denota el rango de destino.
out_range - El rango de destino.

Valor de retorno

{ifirst + N, ofirst + N}.

Complejidad

𝓞(N).

Excepciones

La excepción lanzada en la construcción de los elementos en el rango de destino, si hay alguna.

Notas

Una implementación puede mejorar la eficiencia de ranges::uninitialized_copy si el tipo valor del rango de salida es TrivialType.

Posible implementación

struct uninitialized_copy_fn {
    template <std::input_iterator I, std::sentinel_for<I> S1,
             no-throw-forward-iterator O, no-throw-sentinel-for<O> S2>
    requires std::constructible_from<std::iter_value_t<O>, std::iter_reference_t<I>>
    ranges::uninitialized_copy_result<I, O>
    operator()( I ifirst, S1 ilast, O ofirst, S2 olast ) const {
        O current {ofirst};
        try {
            for (; !(ifirst == ilast or current == olast); ++ifirst, ++current)
                ranges::construct_at(std::addressof(*current), *ifirst);
            return {std::move(ifirst), std::move(current)};
        } catch (...) { // rollback: destruir elementos construidos
            for (; ofirst != current; ++ofirst)
                ranges::destroy_at(std::addressof(*ofirst));
            throw;
        }
    }

    template <ranges::input_range IR, no-throw-forward-range OR>
    requires std::constructible_from<ranges::range_value_t<OR>,
             ranges::range_reference_t<IR>>
    ranges::uninitialized_copy_result<ranges::borrowed_iterator_t<IR>,
             ranges::borrowed_iterator_t<OR>>
    operator()( IR&& in_range, OR&& out_range ) const {
        return (*this)(ranges::begin(in_range), ranges::end(in_range),
                       ranges::begin(out_range), ranges::end(out_range));
    }
};

inline constexpr uninitialized_copy_fn uninitialized_copy{};

Ejemplo

#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <memory>
#include <string>

int main()
{
    const char* v[] { "Este", "es", "un", "ejemplo", };

    if (const auto sz{std::size(v)};
        void* pbuf = std::aligned_alloc(alignof(std::string), sizeof(std::string) * sz))
    {
        try
        {
            auto first {static_cast<std::string*>(pbuf)};
            auto last {first + sz};
            std::ranges::uninitialized_copy(std::begin(v), std::end(v), first, last);

            std::cout << "{ ";
            for (auto it {first}; it != last; ++it)
                std::cout << std::quoted(*it) << ", ";
            std::cout << "};\n";

            std::ranges::destroy(first, last);
        }
        catch(...)
        {
            std::cout << "Excepción en uninitialized_copy \n";
        }
        std::free(pbuf);
    }
}

Salida:

{ "Este", "es", "un", "ejemplo", };

Véase también

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