std::uninitialized_default_construct
Von cppreference.com
| Definiert in Header <memory> |
||
template< class NoThrowForwardIt > void uninitialized_default_construct( NoThrowForwardIt first, NoThrowForwardIt last ); |
(1) | (seit C++17) (constexpr seit C++26) |
| template< class ExecutionPolicy, class NoThrowForwardIt > void uninitialized_default_construct( ExecutionPolicy&& policy, |
(2) | (seit C++17) |
1) Konstruiert Objekte vom Typ typename std::iterator_traits<NoThrowForwardIt>::value_type im uninitialisierten Speicherbereich
[first, last) durch Default-Initialisierung, als ob durch
for (; first != last; ++first)
::new (voidify(*first))
typename std::iterator_traits<NoThrowForwardIt>::value_type;
Wenn während der Initialisierung eine Ausnahme ausgelöst wird, werden die bereits konstruierten Objekte in nicht spezifizierter Reihenfolge zerstört.
2) Wie (1), wird aber gemäß policy ausgeführt.
Diese Überladung nimmt an der Überladungsauflösung teil, nur wenn alle folgenden Bedingungen erfüllt sind
|
std::is_execution_policy_v<std::decay_t<ExecutionPolicy>> ist true. |
(bis C++20) |
|
std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>> ist true. |
(seit C++20) |
Inhalt |
[edit] Parameter
| first, last | - | das Iterator-Paar, das den Bereich der zu initialisierenden Elemente definiert |
| policy | - | die Ausführungsrichtlinie, die verwendet werden soll |
| Typanforderungen | ||
-NoThrowForwardIt muss die Anforderungen von LegacyForwardIterator erfüllen. | ||
-Keine Inkrement-, Zuweisungs-, Vergleichs- oder Dereferenzierungsoperationen über gültige Instanzen von NoThrowForwardIt dürfen Ausnahmen auslösen. | ||
[edit] Komplexität
Linear zur Distanz zwischen first und last.
[edit] Ausnahmen
Die Überladung mit einem Template-Parameter namens ExecutionPolicy meldet Fehler wie folgt
- Wenn die Ausführung einer Funktion, die als Teil des Algorithmus aufgerufen wird, eine Ausnahme auslöst und
ExecutionPolicyeine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andereExecutionPolicyist das Verhalten implementierungsabhängig. - Wenn dem Algorithmus der Speicher zur Neuzuweisung fehlt, wird std::bad_alloc ausgelöst.
[edit] Hinweise
| Feature-Test-Makro | Wert | Std | Feature |
|---|---|---|---|
__cpp_lib_raw_memory_algorithms |
202411L |
(C++26) | constexpr für spezialisierte Speicher-Algorithmen, (1) |
[edit] Mögliche Implementierung
template<class NoThrowForwardIt> constexpr void uninitialized_default_construct(NoThrowForwardIt first, NoThrowForwardIt last) { using Value = typename std::iterator_traits<NoThrowForwardIt>::value_type; NoThrowForwardIt current = first; try { for (; current != last; ++current) { ::new (static_cast<void*>(std::addressof(*current))) Value; } } catch (...) { std::destroy(first, current); throw; } } |
[edit] Beispiel
Führen Sie diesen Code aus
#include <cstring> #include <iostream> #include <memory> #include <string> struct S { std::string m{"Default value"}; }; int main() { constexpr int n{3}; alignas(alignof(S)) unsigned char mem[n * sizeof(S)]; try { auto first{reinterpret_cast<S*>(mem)}; auto last{first + n}; std::uninitialized_default_construct(first, last); for (auto it{first}; it != last; ++it) std::cout << it->m << '\n'; std::destroy(first, last); } catch (...) { std::cout << "Exception!\n"; } // For scalar types, uninitialized_default_construct // generally does not zero-fill the given uninitialized memory area. int v[]{1, 2, 3, 4}; const int original[]{1, 2, 3, 4}; std::uninitialized_default_construct(std::begin(v), std::end(v)); // Maybe undefined behavior, pending CWG 1997 to be resolved. // for (const int i : v) // std::cout << i << ' '; // The result is unspecified. std::cout << (std::memcmp(v, original, sizeof(v)) == 0 ? "Unmodified\n" : "Modified\n"); }
Mögliche Ausgabe
Default value Default value Default value Unmodified
[edit] Defect Reports
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| LWG 3870 | C++20 | dieser Algorithmus kann Objekte auf einem const Speicher erstellen | nicht erlaubt |
[edit] Siehe auch
| konstruiert Objekte mittels Standardinitialisierung in einem uninitialisierten Speicherbereich, definiert durch einen Start und eine Anzahl (Funktions-Template) | |
| konstruiert Objekte mittels Wertinitialisierung in einem uninitialisierten Speicherbereich, definiert durch einen Bereich (Funktions-Template) | |
| konstruiert Objekte mittels Standardinitialisierung in einem uninitialisierten Speicherbereich, definiert durch einen Bereich (Algorithmus-Funktionsobjekt) |