Namespaces
Variants

std::uninitialized_move_n

Von de.cppreference.net
 
 
Algorithmusbibliothek
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
Erzeugungsoperationen
Entfernungsoperationen
Reihenfolgeändernde Operationen
(bis C++17)(C++11)
(C++20)(C++20)
Stichprobenoperationen
(C++17)

Sortier- und zugehörige Operationen
Partitionierungsoperationen
(C++11)    

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


 
 
Definiert in Header <memory>
template< class InputIt, class Size, class NoThrowForwardIt >
std::pair<InputIt, NoThrowForwardIt>
    uninitialized_move_n( InputIt first, Size count,
                          NoThrowForwardIt d_first );
(1) (seit C++17)
(constexpr seit C++26)
template< class ExecutionPolicy,
          class ForwardIt, class Size, class NoThrowForwardIt >
std::pair<ForwardIt, NoThrowForwardIt>
    uninitialized_move_n( ExecutionPolicy&& policy, ForwardIt first,
                          Size count, NoThrowForwardIt d_first );
(2) (seit C++17)
1) Konstruiert Elemente im Zielbereich beginnend bei d_first aus den ersten count Elementen im Quellbereich beginnend bei first wie durch

for (; count > 0; ++d_first, (void) ++first, --count)
    ::new (voidify(*d_first))
        typename std::iterator_traits<NoThrowForwardIt>::value_type(deref-move(*iter));
return {first, d_first};

Wenn während der Initialisierung eine Ausnahme ausgelöst wird, verbleiben einige Objekte in first + [0, count) in einem gültigen, aber nicht spezifizierten Zustand, und die bereits konstruierten Objekte werden in einer nicht spezifizierten Reihenfolge zerstört.
2) 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, count) sich mit first + [0, count) überschneidet, ist das Verhalten undefiniert.

(seit C++20)

Parameter

first - der Anfang des Bereichs der zu verschiebenden Elemente
d_first - der Anfang des Zielbereichs
count - die Anzahl der zu verschiebenden Elemente
policy - die Ausführungsrichtlinie zu verwenden
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 auslösen.

Rückgabewert

Wie oben beschrieben.

Ausnahmen

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

Anmerkungen

Wenn der Eingabe-Iterator auf einen R-Wert dereferenziert, ist das Verhalten von std::uninitialized_move_n dasselbe wie std::uninitialized_copy_n.

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

Mögliche Implementierung

template<class InputIt, class Size, class NoThrowForwardIt>
constexpr std::pair<InputIt, NoThrowForwardIt>
    uninitialized_move_n(InputIt first, Size count, NoThrowForwardIt d_first)
{
    using ValueType = typename std::iterator_traits<NoThrowForwardIt>::value_type;
    NoThrowForwardIt current = d_first;
    try
    {
        for (; count > 0; ++first, (void) ++current, --count) {
            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);
        }
    }
    catch (...)
    {
        std::destroy(d_first, current);
        throw;
    }
    return {first, current};
}

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[]{"One", "Definition", "Rule"};
    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_n(std::begin(in), sz, 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: "One" "Definition" "Rule" 
after move, in: "" "" "" 
after move, out: "One" "Definition" "Rule"

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 3918 C++17 Move-Konstruktion wird immer durchgeführt, auch
wenn der Eingabe-Iterator auf einen Prvalue dereferenziert
keine Move-Konstruktion
in diesem Fall

Siehe auch

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