Espacios de nombres
Variantes

std::ranges::uninitialized_copy_n, std::ranges::uninitialized_copy_n_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, no-throw-input-iterator O, no-throw-sentinel-for<O> S > requires std::constructible_from<std::iter_value_t<O>, std::iter_reference_t<I>> uninitialized_copy_n_result<I, O> uninitialized_copy_n( I ifirst, std::iter_difference_t<I> count, O ofirst, S olast );
(1) (desde C++20)
Tipos auxiliares
template<class I, class O> using uninitialized_copy_n_result = ranges::in_out_result<I, O>;
(2) (desde C++20)

Sea N ranges::min(count, 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 que comienza en ifirst.

El rango de entrada [ifirst, ifirst + count) no debe superponerse con el rango de salida [ofirst, olast).

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 equivalente a:

auto ret = ranges::uninitialized_copy(std::counted_iterator(ifirst, count),
                                      std::default_sentinel, ofirst, olast);
return {std::move(ret.in).base(), ret.out};

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 - El comienzo del rango de elementos del que copiar.
count - El número de elementos a copiar.
ofirst, olast - Par iterador-centinela que denota 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 existe.

Notas

Una implementación puede mejorar la eficiencia de ranges::uninitialized_copy_n, by using e.g. ranges::copy_n, si el tipo valor del rango de salida es TrivialType.

Posible implementación

struct uninitialized_copy_n_fn {
    template <std::input_iterator I, no-throw-input-iterator O, no-throw-sentinel-for<O> S>
    requires std::constructible_from<std::iter_value_t<O>, std::iter_reference_t<I>>
    ranges::uninitialized_copy_n_result<I, O>
    operator()( I ifirst, std::iter_difference_t<I> count, O ofirst, S olast ) const {
        O current {ofirst};
        try {
            for (; count > 0 && current != olast; ++ifirst, ++current, --count)
                ranges::construct_at(std::addressof(*current), *ifirst);
            return {std::move(ifirst), std::move(current)};
        } catch (...) { // rollback: destruir los elementos construidos
            for (; ofirst != current; ++ofirst)
                ranges::destroy_at(std::addressof(*ofirst));
            throw;
        }
    }
};

inline constexpr uninitialized_copy_n_fn uninitialized_copy_n{};

Ejemplo

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

int main()
{
    const char* stars[] { "Procyon", "Spica", "Pollux", "Deneb", "Polaris", };

    constexpr int n {4};
    alignas(alignof(std::string)) char out[n * sizeof(std::string)];

    try
    {
        auto first {reinterpret_cast<std::string*>(out)};
        auto last {first + n};
        auto ret {std::ranges::uninitialized_copy_n(std::begin(stars), n, first, last)};

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

        std::ranges::destroy(first, last);
    }
    catch(...)
    {
        std::cout << "uninitialized_copy_n exception\n";
    }
}

Salida:

{ "Procyon", "Spica", "Pollux", "Deneb", };

Véase también

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