std::ranges:: uninitialized_default_construct
|
Défini dans l'en-tête
<memory>
|
||
|
Signature d'appel
|
||
|
template
<
no-throw-forward-iterator
I, no
-
throw
-
sentinel
-
for
<
I
>
S
>
requires
std::
default_initializable
<
std::
iter_value_t
<
I
>>
|
(1) |
(depuis C++20)
(constexpr depuis C++26) |
|
template
<
no-throw-forward-range
R
>
requires
std::
default_initializable
<
ranges::
range_value_t
<
R
>>
|
(2) |
(depuis C++20)
(constexpr depuis C++26) |
[
first
,
last
)
par
initialisation par défaut
, comme par
for
(
;
first
!
=
last
;
++
first
)
::
new
(
voidify
(
*
first
)
)
std::
remove_reference_t
<
std::
iter_reference_t
<
I
>>
;
return
first
;
Les entités de type fonction décrites sur cette page sont des objets fonction d'algorithmes (informellement appelés niebloids ), c'est-à-dire :
- Les listes d'arguments de modèle explicites ne peuvent pas être spécifiées lors de l'appel de l'une d'entre elles.
- Aucune d'entre elles n'est visible pour la recherche dépendante des arguments .
- Lorsque l'une d'entre elles est trouvée par la recherche non qualifiée normale comme nom à gauche de l'opérateur d'appel de fonction, la recherche dépendante des arguments est inhibée.
Table des matières |
Paramètres
| first, last | - | la paire itérateur-sentinelle définissant la plage des éléments à initialiser |
| r | - |
la
range
des éléments à initialiser
|
Valeur de retour
Comme décrit ci-dessus.
Complexité
Linéaire en fonction de la distance entre first et last .
Exceptions
Toute exception levée lors de la construction des éléments dans la plage de destination.
Notes
Une implémentation peut omettre la construction des objets (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 std:: iter_value_t < I > objet, ce qui peut être détecté par std::is_trivially_default_constructible .
| Macro de test de fonctionnalité | Valeur | Std | Fonctionnalité |
|---|---|---|---|
__cpp_lib_raw_memory_algorithms
|
202411L
|
(C++26) | constexpr pour les algorithmes de mémoire spécialisés , ( 1,2 ) |
Implémentation possible
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); // ignorer l'initialisation I rollback{first}; try { for (; !(first == last); ++first) ::new (static_cast<void*>(std::addressof(*first))) ValueType; return first; } catch (...) // restauration : détruire les éléments construits { 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{}; |
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
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Applicable à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| LWG 3870 | C++20 | cet algorithme pourrait créer des objets sur un stockage const | maintenu interdit |
Voir aussi
|
construit des objets par
default-initialization
dans une zone mémoire non initialisée, définie par un début et un compte
(objet fonction algorithme) |
|
|
construit des objets par
value-initialization
dans une zone mémoire non initialisée, définie par une plage
(objet fonction algorithme) |
|
|
construit des objets par
value-initialization
dans une zone mémoire non initialisée, définie par un début et un compte
(objet fonction algorithme) |
|
|
(C++17)
|
construit des objets par
default-initialization
dans une zone mémoire non initialisée, définie par une plage
(modèle de fonction) |