Namensräume
Varianten
Aktionen

std::uninitialized_default_construct_n

Von cppreference.com
< cpp‎ | memory
 
 
Speicherverwaltungsbibliothek
(nur Exposition*)
Algorithmen für uninitialisierten Speicher
(C++17)
(C++17)
uninitialized_default_construct_n
(C++17)
(C++17)
Beschränkte uninitialisierte
Speicher-Algorithmen
C-Bibliothek

Allocatoren
Speicherressourcen
Unterstützung für Garbage Collection
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
(C++11)(bis C++23)
Uninitialisierter Speicher
Explizites Lebenszeitmanagement
 
Definiert in Header <memory>
template< class NoThrowForwardIt, class Size >

NoThrowForwardIt uninitialized_default_construct_n

    ( NoThrowForwardIt first, Size count );
(1) (seit C++17)
(constexpr seit C++26)
template< class ExecutionPolicy, class NoThrowForwardIt, class Size >

NoThrowForwardIt uninitialized_default_construct_n

    ( ExecutionPolicy&& policy, NoThrowForwardIt first, Size count );
(2) (seit C++17)
1) Konstruiert Objekte vom Typ typename std::iterator_traits<NoThrowForwardIt>::value_type im uninitialisierten Speicherbereich first + [0count) durch Default-Initialisierung, als ob durch

for (; count > 0; (void)++first, --count)
    ::new (voidify(*first))
        typename std::iterator_traits<NoThrowForwardIt>::value_type;
return first;

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

[bearbeiten] Parameter

first - der Anfang des zu initialisierenden Bereichs von Elementen
zählt - die Anzahl der zu konstruierenden Elemente
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.

[bearbeiten] Rückgabewert

Wie oben beschrieben.

[bearbeiten] Komplexität

Linear in n.

[bearbeiten] 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 ExecutionPolicy eine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jede andere ExecutionPolicy ist das Verhalten implementierungsabhängig.
  • Wenn dem Algorithmus der Speicher zur Neuzuweisung fehlt, wird std::bad_alloc ausgelöst.

[bearbeiten] Hinweise

Feature-Test-Makro Wert Std Feature
__cpp_lib_raw_memory_algorithms 202411L (C++26) constexpr für spezialisierte Speicher-Algorithmen, (1)

[bearbeiten] Mögliche Implementierung

template<class NoThrowForwardIt, class Size>
constexpr ForwardIt uninitialized_default_construct_n(NoThrowForwardIt first, Size count)
{
    using T = typename std::iterator_traits<NoThrowForwardIt>::value_type;
    NoThrowForwardIt current = first;
 
    try
    {
        for (; countn > 0; (void) ++current, --count)
            ::new (static_cast<void*>(std::addressof(*current))) T;
        return current;
    }
    catch (...)
    {
        std::destroy(first, current);
        throw;
    }
}

[bearbeiten] Beispiel

#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 = std::uninitialized_default_construct_n(first, n);
 
        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_n
    // generally does not zero-initialize the given uninitialized memory area.
    int v[]{1, 2, 3, 4};
    const int original[]{1, 2, 3, 4};
    std::uninitialized_default_construct_n(std::begin(v), std::size(v));
 
    // An attempt to access v might be an 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 ? "un" : "") << "modified\n";
}

Mögliche Ausgabe

default value
default value
default value
unmodified

[bearbeiten] Fehlerberichte

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

[bearbeiten] Siehe auch

konstruiert Objekte mittels Standardinitialisierung in einem uninitialisierten Speicherbereich, definiert durch einen Bereich
(Funktions-Template) [edit]
konstruiert Objekte mittels Wertinitialisierung in einem uninitialisierten Speicherbereich, definiert durch einen Start und eine Anzahl
(Funktions-Template) [edit]
konstruiert Objekte mittels Standardinitialisierung in einem uninitialisierten Speicherbereich, definiert durch Start und Anzahl
(Algorithmus-Funktionsobjekt)[edit]