Namensräume
Varianten
Aktionen

std::uninitialized_move

Von cppreference.com
< cpp‎ | memory
 
 
Speicherverwaltungsbibliothek
(nur Exposition*)
Algorithmen für uninitialisierten Speicher
uninitialized_move
(C++17)
(C++17)
(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 InputIt, class NoThrowForwardIt >

NoThrowForwardIt uninitialized_move( InputIt first, InputIt last,

                                     NoThrowForwardIt d_first );
(1) (seit C++17)
(constexpr seit C++26)
template< class ExecutionPolicy,

          class ForwardIt, class NoThrowForwardIt >
NoThrowForwardIt uninitialized_move( ExecutionPolicy&& policy,
                                     ForwardIt first, ForwardIt last,

                                     NoThrowForwardIt d_first );
(2) (seit C++17)
1) Kopiert die Elemente aus [firstlast) (unter Verwendung von Move-Semantik, falls unterstützt) in einen uninitialisierten Speicherbereich beginnend bei d_first, als ob durch

for (; first != last; ++d_first, (void) ++first)
    ::new (voidify(*d_first))
        typename std::iterator_traits<NoThrowForwardIt>::value_type(/* value */);
return d_first;

wobei /* value */ std::move(*first) ist, wenn *first ein lvalue-Referenztyp ist, oder *first andernfalls.
Wenn während der Initialisierung eine Ausnahme ausgelöst wird, bleiben einige Objekte in [firstlast) in einem gültigen, aber nicht spezifizierten Zustand, und die bereits konstruierten Objekte werden 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)


Wenn d_first + [0std::distance(first, last)) mit [firstlast) überlappt, ist das Verhalten undefiniert.

(seit C++20)

Inhalt

[bearbeiten] Parameter

first, last - das Iteratorenpaar, das den Bereich der zu verschiebenden Elemente definiert
d_first - der Anfang des Zielbereichs
policy - die Ausführungsrichtlinie, die verwendet werden soll
Typanforderungen
-
InputIt muss die Anforderungen von LegacyInputIterator erfüllen.
-
ForwardIt muss die Anforderungen von LegacyForwardIterator erfüllen.
-
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 zur Distanz zwischen first und last.

[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

Wenn der Eingabeiterator auf ein rvalue dereferenziert, ist das Verhalten von std::uninitialized_move dasselbe wie bei std::uninitialized_copy.

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 InputIt, class NoThrowForwardIt>
constexpr NoThrowForwardIt uninitialized_move(InputIt first, InputIt last,
                                              NoThrowForwardIt d_first)
{
    using ValueType = typename std::iterator_traits<NoThrowForwardIt>::value_type;
    auto current = d_first;
    try
    {
        for (; first != last; ++first, (void) ++current)
        {
            auto addr = static_cast<void*>(std::addressof(*current));
            if constexpr (std::is_lvalue_reference_v<decltype(*first)>)
                ::new (addr) ValueType(std::move(*first));
            else
                ::new (addr) ValueType(*first);
        }
        return current;
    }
    catch (...)
    {
        std::destroy(d_first, current);
        throw;
    }
}

[bearbeiten] Beispiel

#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <memory>
#include <string>
 
void print(auto rem, auto first, auto last)
{
    for (std::cout << rem; first != last; ++first)
        std::cout << std::quoted(*first) << ' ';
    std::cout << '\n';
}
 
int main()
{
    std::string in[]{"Home", "Work!"};
    print("initially, in: ", std::begin(in), std::end(in));
 
    if (
        constexpr auto sz = std::size(in);
        void* out = std::aligned_alloc(alignof(std::string), sizeof(std::string) * sz))
    {
        try
        {
            auto first{static_cast<std::string*>(out)};
            auto last{first + sz};
            std::uninitialized_move(std::begin(in), std::end(in), first);
 
            print("after move, in: ", std::begin(in), std::end(in));
            print("after move, out: ", first, last);
 
            std::destroy(first, last);
        }
        catch (...)
        {
            std::cout << "Exception!\n";
        }
        std::free(out);
    }
}

Mögliche Ausgabe

initially, in: "Home" "Work!"
after move, in: "" ""
after move, out: "Home" "Work!"

[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
LWG 3918 C++17 zusätzliche temporäre Materialisierung war erforderlich
wenn der Eingabeiterator auf ein prvalue dereferenziert
kopiert das Element in diesem Fall

[bearbeiten] Siehe auch

kopiert einen Bereich von Objekten in einen uninitialisierten Speicherbereich
(Funktions-Template) [edit]
verschiebt eine Anzahl von Objekten in einen uninitialisierten Speicherbereich
(Funktions-Template) [edit]
verschiebt einen Bereich von Objekten in einen uninitialisierten Speicherbereich
(Algorithmus-Funktionsobjekt)[edit]