Namespaces
Variants

std::ranges::uninitialized_default_construct

De fr.cppreference.net
 
 
Bibliothèque d'algorithmes
Algorithmes contraints et algorithmes sur les plages (C++20)
Algorithmes contraints, par ex. ranges::copy, ranges::sort, ...
Opérations de séquence non modificatrices    
Opérations en bloc
(C++17)
Opérations de recherche
Opérations de séquence modificatrices
Opérations de copie
(C++11)
(C++11)
Opérations d'échange
Opérations de transformation
Opérations de génération
Opérations de suppression
Opérations de changement d'ordre
(jusqu'à C++17)(C++11)
(C++20)(C++20)
Opérations d'échantillonnage
(C++17)

Tri et opérations connexes
Opérations de partitionnement
(C++11)    

Opérations de tri
Opérations de recherche binaire
(sur des plages partitionnées)
Opérations ensemblistes (sur des plages triées)
Opérations de fusion (sur des plages triées)
Opérations de tas
Opérations minimum/maximum
(C++11)
(C++17)
Opérations de comparaison lexicographique
Opérations de permutation


 
 
Défini dans l'en-tête <memory>
Signature d'appel
template< /*nothrow-forward-iterator*/ I, /*nothrow-sentinel-for*/<I> S >
    requires std::default_initializable<std::iter_value_t<I>>
I uninitialized_default_construct( I first, S last );
(1) (depuis C++20)
(constexpr depuis C++26)
template< /*nothrow-forward-range*/ R >
    requires std::default_initializable<ranges::range_value_t<R>>
ranges::borrowed_iterator_t<R>
    uninitialized_default_construct( R&& r );
(2) (depuis C++20)
(constexpr depuis C++26)
template< /*execution-policy*/ Ep, /*nothrow-random-access-iterator*/ I,
          /*nothrow-sized-sentinel-for*/<I> S >
    requires std::default_initializable<std::iter_value_t<I>>
I uninitialized_default_construct( Ep&& policy, I first, S last );
(3) (depuis C++26)
template< /*execution-policy*/ Ep, /*nothrow-sized-random-access-range*/ R >
    requires std::default_initializable<ranges::range_value_t<R>>
ranges::borrowed_iterator_t<R>
    uninitialized_default_construct( Ep&& policy, R&& r );
(4) (depuis C++26)

Pour la définition de /*execution-policy*/, voir cette page ; pour la définition des autres concepts d'exposition uniquement, voir cette page.

1) Construit des éléments dans la plage de destination [firstlast) par initialisation par défaut comme si par

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

Si une exception est levée pendant l'initialisation, les objets déjà construits sont détruits dans un ordre non spécifié.
2) Identique à (1), mais utilise r comme plage de destination.
3,4) Identique à (1,2), mais exécuté selon policy.

Les entités de type fonction décrites sur cette page sont des objets fonctions d'algorithme (informellement appelés niebloids), c'est-à-dire :

Paramètres

first, last - la paire itérateur-sentinelle définissant la plage d'éléments à initialiser
r - la plage des éléments à initialiser
policy - la politique d'exécution à utiliser

Valeur de retour

Comme décrit ci-dessus.

Exceptions

Toute exception levée lors de la construction des éléments dans la plage de destination.

3,4) Pendant le processus d'exécution :
  • Si les ressources mémoire temporaires nécessaires à la parallélisation ne sont pas disponibles, std::bad_alloc est levée.
  • Si une exception non interceptée est levée lors de l'accès à des objets via un argument d'algorithme, le comportement est déterminé par la politique d'exécution (pour les politiques standard, std::terminate est invoqué).

Notes

Une implémentation peut ignorer la construction de l'objet (sans modifier l'effet observable) si aucun constructeur par défaut non trivial n'est appelé lors de l'initialisation par défaut d'un objet std::iter_value_t<I>, ce qui peut être détecté par std::is_trivially_default_constructible.

Test de fonctionnalité macro Valeur Norme Fonctionnalité
__cpp_lib_parallel_algorithm 202506L (C++26) Algorithmes de plage parallèles
__cpp_lib_raw_memory_algorithms 202411L (C++26) constexpr pour spécialisés <memory> algorithmes, (1,2)

Implémentation possible

struct uninitialized_default_construct_fn
{
    template</*nothrow-forward-iterator*/ I, /*nothrow-sentinel-for*/<I> S>
        requires std::default_initializable<std::iter_value_t<I>>
    constexpr I operator()(I first, S last) const
    {
        using value_type = std::remove_reference_t<std::iter_reference_t<I>>;
        if constexpr (std::is_trivially_default_constructible_v<value_type>)
            return ranges::next(first, last); // skip initialization
        I rollback{first};
        try
        {
            for (; !(first == last); ++first)
                ::new (static_cast<void*>(std::addressof(*first))) value_type;
            return first;
        }
        catch (...) // rollback: destroy constructed elements
        {
            for (; rollback != first; ++rollback)
                ranges::destroy_at(std::addressof(*rollback));
            throw;
        }
    }
    
    template</*nothrow-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::next(ranges::begin(r), ranges::end(r)));
    }
};

inline constexpr uninitialized_default_construct_fn uninitialized_default_construct{};

Exemple

#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"; }
    // Notez que pour les "types triviaux", uninitialized_default_construct
    // ne remplit généralement pas de zéros la zone mémoire non initialisée donnée.
    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 << "  ";
        // Comportement potentiellement indéfini, en attente de résolution CWG 1997 :
        // for (const char c : v) { std::cout << c << ' '; }
        for (const char c : sample)
            std::cout << c << ' ';
    }
    else
        std::cout << "Non spécifié\n";
}

Sortie possible :

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

Voir aussi

construit des objets par initialisation par défaut dans une zone mémoire non initialisée, définie par un début et un nombre
(objet fonction d'algorithme)
construit des objets par initialisation par valeur dans une zone mémoire non initialisée, définie par un intervalle
(objet fonction d'algorithme)
construit des objets par initialisation par valeur dans une zone mémoire non initialisée, définie par un début et un nombre
(objet fonction d'algorithme)
construit des objets par initialisation par défaut dans une zone mémoire non initialisée, définie par un intervalle
(modèle de fonction)