Namespaces
Variants

std::uninitialized_move

Von de.cppreference.net
 
 
Algorithmen-Bibliothek
Eingeschränkte Algorithmen und Algorithmen auf Bereichen (C++20)
Eingeschränkte Algorithmen, z. B. ranges::copy, ranges::sort, ...
Nicht modifizierende Sequenzoperationen    
Stapeloperationen
(C++17)
Suchoperationen
Modifizierende Sequenzoperationen
Kopieroperationen
(C++11)
(C++11)
Tauschoperationen
Transformationsoperationen
Generierungsoperationen
Entfernungsoperationen
Reihenfolgeändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und verwandte Operationen
Partitionierungsoperationen
(C++11)    

Sortieroperationen
Binäre Suchoperationen
(auf partitionierten Bereichen)
Mengenoperationen (auf sortierten Bereichen)
Mischoperationen (auf sortierten Bereichen)
Heap-Operationen
Minimum/Maximum-Operationen
(C++11)
(C++17)
Lexikografische Vergleichsoperationen
Permutationsoperationen


 
 
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) Konstruiert Elemente im Zielbereich beginnend bei d_first aus Elementen des Quellbereichs [first, last) wie durch

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

Wenn während der Initialisierung eine Ausnahme ausgelöst wird, bleiben einige Objekte in [first, last) in einem gültigen, aber nicht spezifizierten Zustand, und die bereits konstruierten Objekte werden in einer nicht spezifizierten Reihenfolge zerstört.
2) Gleich wie (1), aber ausgeführt gemäß policy.
Diese Überladung nimmt nur an der Überladungsauflösung teil, wenn der Wert des folgenden Ausdrucks true ist:

std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>

(bis C++20)

std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>

(seit C++20)


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

(seit C++20)

Parameter

first, last - das Paar von Iteratoren, das den Bereich der zu verschiebenden Elemente definiert
d_first - der Anfang des Zielbereichs
policy - die zu verwendende Ausführungsrichtlinie
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.
-
Durch gültige Instanzen von NoThrowForwardIt dürfen keine Inkrement-, Zuweisungs-, Vergleichs- oder Dereferenzierungsoperationen Ausnahmen werfen.

Rückgabewert

Wie oben beschrieben.

Ausnahmen

2) Während des Ausführungsprozesses:
  • Falls die für die Parallelisierung benötigten temporären Speicherressourcen nicht verfügbar sind, wird std::bad_alloc ausgelöst.
  • Falls beim Zugriff auf Objekte über ein Algorithmusargument eine nicht gefangene Ausnahme ausgelöst wird, wird das Verhalten durch die Ausführungsrichtlinie bestimmt (für Standardrichtlinien, wird std::terminate aufgerufen).

Anmerkungen

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

Feature-Test Makro Wert Standard Merkmal
__cpp_lib_raw_memory_algorithms 202411L (C++26) constexpr für spezialisierte <memory>Algorithmen, (1)

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;
    }
}

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!"

Fehlerberichte

Die folgenden verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR Angewendet auf Verhalten wie veröffentlicht Korrektes Verhalten
LWG 3918 C++17 Die Move-Konstruktion wird immer durchgeführt, auch
wenn der Eingabe-Iterator auf einen Prvalue dereferenziert
keine Move-Konstruktion
in diesem Fall

Siehe auch

kopiert eine Reihe von Objekten in einen nicht initialisierten Speicherbereich
(Funktions-Template)
verschiebt eine Anzahl von Objekten in einen nicht initialisierten Speicherbereich
(Funktions-Template)
verschiebt eine Reihe von Objekten in einen nicht initialisierten Speicherbereich
(Algorithmus-Funktionsobjekt)