1. "Was ist das?"
Während std::move()
technisch eine Funktion ist - ich würde sagen, es ist nicht wirklich eine Funktion . Es ist eine Art Konverter zwischen den Methoden, mit denen der Compiler den Wert eines Ausdrucks berücksichtigt.
2. "Was macht es?"
Das erste, was zu beachten ist, ist, dass std::move()
sich nichts bewegt . Es konvertiert einen Ausdruck von einem l-Wert (z. B. einer benannten Variablen) in einen x-Wert . Ein xvalue teilt dem Compiler mit:
Du kannst mich plündern, alles , was ich halte , bewegen und woanders verwenden (da ich sowieso bald zerstört werde) ".
Mit anderen Worten, wenn Sie verwenden std::move(x)
, lassen Sie den Compiler ausschlachten x
. Wenn x
also beispielsweise ein eigener Puffer im Speicher vorhanden ist, std::move()
kann der Compiler nach dem Erstellen stattdessen ein anderes Objekt besitzen.
Sie können auch von einem Wert wechseln (z. B. von einem temporären Wert, den Sie herumgeben ), dies ist jedoch selten nützlich.
3. "Wann sollte es verwendet werden?"
Eine andere Möglichkeit, diese Frage zu stellen, lautet: "Wofür kann ich die Ressourcen eines vorhandenen Objekts ausschlachten?" Wenn Sie Anwendungscode schreiben, werden Sie wahrscheinlich nicht viel mit temporären Objekten herumspielen, die vom Compiler erstellt wurden. Sie würden dies also hauptsächlich an Orten wie Konstruktoren, Operatormethoden, Standardbibliotheksalgorithmus-ähnlichen Funktionen usw. tun, an denen Objekte häufig automatisch erstellt und zerstört werden. Das ist natürlich nur eine Faustregel.
Eine typische Verwendung besteht darin, Ressourcen von einem Objekt zu einem anderen zu verschieben, anstatt sie zu kopieren. @ Guillaume verlinkt auf diese Seite, die ein einfaches kurzes Beispiel enthält: Vertauschen von zwei Objekten mit weniger Kopieraufwand.
template <class T>
swap(T& a, T& b) {
T tmp(a); // we now have two copies of a
a = b; // we now have two copies of b (+ discarded a copy of a)
b = tmp; // we now have two copies of tmp (+ discarded a copy of b)
}
Mit move können Sie die Ressourcen austauschen, anstatt sie zu kopieren:
template <class T>
swap(T& a, T& b) {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}
Denken Sie daran, was passiert, wenn T
es beispielsweise die vector<int>
Größe n hat. In der ersten Version lesen und schreiben Sie 3 * n Elemente, in der zweiten Version lesen und schreiben Sie im Grunde nur die 3 Zeiger auf die Vektorpuffer plus die 3 Puffergrößen. Natürlich muss die Klasse T
wissen, wie man sich bewegt; Ihre Klasse sollte einen Verschiebungszuweisungsoperator und einen Verschiebungskonstruktor für die Klasse haben, T
damit dies funktioniert.