Namespaces
Variants

std::ranges:: uninitialized_default_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_default_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_default_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 defecto , 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_default_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-sentinel que define el rango de elementos a inicializar
r - el range de los elementos a inicializar

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 omitir la construcción de objetos (sin cambiar el efecto observable) si no se llama a ningún constructor por defecto no trivial al inicializar por defecto un objeto std:: iter_value_t < I > , lo cual puede detectarse mediante std::is_trivially_default_constructible .

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_default_construct_fn
{
    template<no-throw-forward-iterator I, no-throw-sentinel-for<I> S>
        requires std::default_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::next(first, last); // omitir inicialización
        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_default_construct_fn uninitialized_default_construct{};

Ejemplo

#include <cstring>
#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_default_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"; }
    // Nótese que para "tipos triviales" el uninitialized_default_construct
    // generalmente no rellena con ceros el área de memoria no inicializada dada.
    constexpr char sample[]{'A', 'B', 'C', 'D', '\n'};
    char v[]{'A', 'B', 'C', 'D', '\n'};
    std::ranges::uninitialized_default_construct(std::begin(v), std::end(v));
    if (std::memcmp(v, sample, sizeof(v)) == 0)
    {
        std::cout << "  ";
        // Comportamiento posiblemente indefinido, pendiente de resolución CWG 1997:
        // for (const char c : v) { std::cout << c << ' '; }
        for (const char c : sample)
            std::cout << c << ' ';
    }
    else
        std::cout << "No especificado\n";
}

Salida posible:

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

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