std::move
| Definiert in Header <algorithm>
|
||
template< class InputIt, class OutputIt >
OutputIt move( InputIt first, InputIt last,
OutputIt d_first );
|
(1) | (seit C++11) (constexpr seit C++20) |
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >
ForwardIt2 move( ExecutionPolicy&& policy,
ForwardIt1 first, ForwardIt1 last,
ForwardIt2 d_first );
|
(2) | (seit C++17) |
[first, last) in einen anderen Bereich, der bei d_first beginnt, beginnend mit first und fortfahren bis last. Nach dieser Operation enthalten die Elemente im verschobenen Bereich weiterhin gültige Werte des entsprechenden Typs, aber nicht notwendigerweise dieselben Werte wie vor der Verschiebung.policy.true ist:
|
|
(bis C++20) |
|
|
(seit C++20) |
Wenn d_first innerhalb des Bereichs [first, last) liegt, ist das Verhalten undefiniert. In diesem Fall kann stattdessen std::move_backward verwendet werden.
Parameter
| first, last | - | Das Paar von Iteratoren, das den Quell-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.
| ||
-OutputIt muss die Anforderungen von LegacyOutputIterator erfüllen.
| ||
-ForwardIt1, ForwardIt2 muss die Anforderungen von LegacyForwardIterator erfüllen.
| ||
Rückgabewert
Der Iterator zum Element nach dem letzten verschobenen Element.
Komplexität
Genau std::distance(first, last) Verschiebungszuweisungen.
Ausnahmen
Die Überladung mit einem Template-Parameter namens ExecutionPolicy meldet Fehler wie folgt:
- Wenn die Ausführung einer als Teil des Algorithmus aufgerufenen Funktion eine Ausnahme auslöst und
ExecutionPolicyeine der Standardrichtlinien ist, wird std::terminate aufgerufen. Für jedes andereExecutionPolicyist das Verhalten implementierungsdefiniert. - Wenn der Algorithmus keinen Speicher zuweisen kann, wird std::bad_alloc ausgelöst.
Mögliche Implementierung
template<class InputIt, class OutputIt>
OutputIt move(InputIt first, InputIt last, OutputIt d_first)
{
for (; first != last; ++d_first, ++first)
*d_first = std::move(*first);
return d_first;
}
|
Anmerkungen
Beim Verschieben überlappender Bereiche ist std::move geeignet, wenn nach links verschoben wird (Anfang des Zielbereichs liegt außerhalb des Quellbereichs), während std::move_backward geeignet ist, wenn nach rechts verschoben wird (Ende des Zielbereichs liegt außerhalb des Quellbereichs).
Beispiel
Der folgende Code verschiebt Thread-Objekte (die selbst nicht kopierbar sind) von einem Container in einen anderen.
#include <algorithm>
#include <chrono>
#include <iostream>
#include <iterator>
#include <list>
#include <thread>
#include <vector>
void f(int n)
{
std::this_thread::sleep_for(std::chrono::seconds(n));
std::cout << "thread " << n << " ended" << std::endl;
}
int main()
{
std::vector<std::jthread> v;
v.emplace_back(f, 1);
v.emplace_back(f, 2);
v.emplace_back(f, 3);
std::list<std::jthread> l;
// copy() would not compile, because std::jthread is noncopyable
std::move(v.begin(), v.end(), std::back_inserter(l));
}
Ausgabe:
thread 1 ended
thread 2 ended
thread 3 ended
Siehe auch
(C++11) |
verschiebt einen Bereich von Elementen in umgekehrter Reihenfolge an einen neuen Ort (Funktionsschablone & Algorithmus-Funktionsobjekt) |
(C++20) |
|
(C++11) |
wandelt das Argument in einen Xvalue um (Funktionsschablone) |
(C++20) |
verschiebt einen Bereich von Elementen an einen neuen Ort (Algorithmus-Funktionsobjekt) |