std::uninitialized_move
Von de.cppreference.net
| 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:
|
|
(bis C++20) |
|
|
(seit C++20) |
|
Wenn |
(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.
|
||
-
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
Diesen Code ausführen
#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) |
|
|
(C++17)
|
verschiebt eine Anzahl von Objekten in einen nicht initialisierten Speicherbereich
(Funktions-Template) |
|
(C++20)
|
verschiebt eine Reihe von Objekten in einen nicht initialisierten Speicherbereich
(Algorithmus-Funktionsobjekt) |