Namespaces
Variants

std::ranges:: uninitialized_value_construct

From cppreference.net
Memory management library
( exposition only* )
Allocators
Uninitialized memory algorithms
Constrained uninitialized memory algorithms
Memory resources
Uninitialized storage (until C++20)
( until C++20* )
( until C++20* )
( until C++20* )

Garbage collector support (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
(C++11) (until C++23)
Definido en el encabezado <memory>
Firma de llamada
template < no-throw-forward-iterator I, no - throw - sentinel - for < I > S >

requires std:: default_initializable < std:: iter_value_t < I >>

I uninitialized_value_construct ( I first, S last ) ;
(1) (desde C++20)
(constexpr desde C++26)
template < no-throw-forward-range R >

requires std:: default_initializable < ranges:: range_value_t < R >>
ranges:: borrowed_iterator_t < R >

uninitialized_value_construct ( R && r ) ;
(2) (desde C++20)
(constexpr desde C++26)
1) Construye objetos de tipo std:: iter_value_t < I > en el área de memoria no inicializada [ first , last ) mediante inicialización por valor , como si fuera

for ( ; first ! = last ; ++ first )
:: new ( voidify ( * first ) )
std:: remove_reference_t < std:: iter_reference_t < I >> ( ) ;
return first ;

Si se lanza una excepción durante la inicialización, los objetos ya construidos se destruyen en un orden no especificado.
2) Equivalente a ranges :: uninitialized_value_construct ( ranges:: begin ( r ) , ranges:: end ( r ) ) .

Las entidades similares a funciones descritas en esta página son algorithm function objects (conocidas informalmente como niebloids ), es decir:

Contenidos

Parámetros

first, last - el par iterador-centinela que define el rango de elementos a inicializar por valor
r - el range de los elementos a inicializar por valor

Valor de retorno

Como se describió anteriormente.

Complejidad

Lineal en la distancia entre first y last .

Excepciones

Cualquier excepción lanzada durante la construcción de los elementos en el rango de destino.

Notas

Una implementación puede mejorar la eficiencia de ranges::uninitialized_value_construct , por ejemplo utilizando ranges::fill , si el tipo de valor del rango es un CopyAssignable TrivialType .

Macro de prueba de características Valor Estándar Característica
__cpp_lib_raw_memory_algorithms 202411L (C++26) constexpr para algoritmos de memoria especializados , ( 1,2 )

Implementación posible

struct uninitialized_value_construct_fn
{
    template<no-throw-forward-iterator I, no-throw-sentinel-for<I> S>
        requires std::value_initializable<std::iter_value_t<I>>
    constexpr I operator()(I first, S last) const
    {
        using ValueType = std::remove_reference_t<std::iter_reference_t<I>>;
        if constexpr (std::is_trivially_default_constructible_v<ValueType>)
            return ranges::fill(first, last, ValueType());
        I rollback{first};
        try
        {
            for (; !(first == last); ++first)
                ::new (static_cast<void*>(std::addressof(*first))) ValueType();
            return first;
        }
        catch (...) // retroceso: destruir elementos construidos
        {
            for (; rollback != first; ++rollback)
                ranges::destroy_at(std::addressof(*rollback));
            throw;
        }
    }
    template<no-throw-forward-range R>
        requires std::default_initializable<ranges::range_value_t<R>>
    constexpr ranges::borrowed_iterator_t<R> operator()(R&& r) const
    {
        return (*this)(ranges::begin(r), ranges::end(r));
    }
};
inline constexpr uninitialized_value_construct_fn uninitialized_value_construct{};

Ejemplo

#include <iostream>
#include <memory>
#include <string>
int main()
{
    struct S { std::string m{"▄▀▄▀▄▀▄▀"}; };
    constexpr int n{4};
    alignas(alignof(S)) char out[n * sizeof(S)];
    try
    {
        auto first{reinterpret_cast<S*>(out)};
        auto last{first + n};
        std::ranges::uninitialized_value_construct(first, last);
        auto count{1};
        for (auto it{first}; it != last; ++it)
            std::cout << count++ << ' ' << it->m << '\n';
        std::ranges::destroy(first, last);
    }
    catch (...)
    {
        std::cout << "Exception!\n";
    }
    // For scalar types, uninitialized_value_construct
    // zero-fills the given uninitialized memory area.
    int v[]{0, 1, 2, 3};
    std::cout << ' ';
    for (const int i : v)
        std::cout << ' ' << static_cast<char>(i + 'A');
    std::cout << "\n ";
    std::ranges::uninitialized_value_construct(std::begin(v), std::end(v));
    for (const int i : v)
        std::cout << ' ' << static_cast<char>(i + 'A');
    std::cout << '\n';
}

Salida:

1 ▄▀▄▀▄▀▄▀
2 ▄▀▄▀▄▀▄▀
3 ▄▀▄▀▄▀▄▀
4 ▄▀▄▀▄▀▄▀
  A B C D
  A A A A

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 3870 C++20 este algoritmo podría crear objetos en un almacenamiento const se mantiene no permitido

Véase también

construye objetos mediante value-initialization en un área de memoria no inicializada, definida por un inicio y un contador
(objeto función algoritmo)
construye objetos mediante default-initialization en un área de memoria no inicializada, definida por un rango
(objeto función algoritmo)
construye objetos mediante default-initialization en un área de memoria no inicializada, definida por un inicio y contador
(objeto función algoritmo)
construye objetos mediante value-initialization en un área de memoria no inicializada, definida por un rango
(plantilla de función)