Namensräume
Varianten
Aktionen

std::move

Von cppreference.com
< cpp‎ | utility
 
 
Dienstprogramm-Bibliotheken
Sprachunterstützung
Typunterstützung (Basistypen, RTTI)
Bibliotheks-Feature-Test-Makros (C++20)
Programm-Dienstprogramme
Variadische Funktionen
Coroutine-Unterstützung (C++20)
Vertragsunterstützung (C++26)
Drei-Wege-Vergleich
(C++20)
(C++20)(C++20)(C++20)  
(C++20)(C++20)(C++20)

Allgemeine Hilfsmittel
Relationale Operatoren (in C++20 veraltet)
Ganzzahl-Vergleichsfunktionen
(C++20)(C++20)(C++20)  
(C++20)
Swap und Typ-Operationen
(C++14)
(C++11)
(C++11)
move
(C++11)
(C++17)
Gemeinsame Vokabulartypen
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
Definiert in der Header-Datei <utility>
template< class T >
typename std::remove_reference<T>::type&& move( T&& t ) noexcept;
(seit C++11)
(bis C++14)
template< class T >
constexpr std::remove_reference_t<T>&& move( T&& t ) noexcept;
(seit C++14)

std::move wird verwendet, um *anzuzeigen*, dass ein Objekt t "von ihm bewegt" werden darf, d.h. um die effiziente Übertragung von Ressourcen von t auf ein anderes Objekt zu ermöglichen.

Insbesondere erzeugt std::move einen xvalue-Ausdruck, der sein Argument t identifiziert. Es ist exakt äquivalent zu einem static_cast zu einem rvalue-Referenztyp.

Inhalt

[bearbeiten] Parameter

t - das zu bewegende Objekt

[bearbeiten] Rückgabewert

static_cast<typename std::remove_reference<T>::type&&>(t)

[bearbeiten] Hinweise

Die Funktionen, die rvalue-Referenzparameter akzeptieren (einschließlich Move-Konstruktoren, Move-Zuweisungsoperatoren und reguläre Member-Funktionen wie std::vector::push_back) werden durch Überladungsauflösung ausgewählt, wenn sie mit rvalue-Argumenten aufgerufen werden (entweder prvalues wie ein temporäres Objekt oder xvalues wie die von std::move erzeugten). Wenn das Argument ein ressourcenhaltendes Objekt identifiziert, haben diese Überladungen die Option, aber nicht die Pflicht, alle vom Argument gehaltenen Ressourcen zu *verschieben*. Zum Beispiel könnte ein Move-Konstruktor einer verknüpften Liste den Zeiger auf den Kopf der Liste kopieren und nullptr im Argument speichern, anstatt einzelne Knoten zuzuweisen und zu kopieren.

Namen von rvalue-Referenz-Variablen sind lvalues und müssen in xvalues konvertiert werden, um an die Funktionsüberladungen gebunden zu werden, die rvalue-Referenzparameter akzeptieren. Deshalb verwenden Move-Konstruktoren und Move-Zuweisungsoperatoren typischerweise std::move.

// Simple move constructor
A(A&& arg) : member(std::move(arg.member)) // the expression "arg.member" is lvalue
{}
 
// Simple move assignment operator
A& operator=(A&& other)
{
    member = std::move(other.member);
    return *this;
}

Eine Ausnahme bildet, wenn der Typ des Funktionsparameters eine Forwarding-Referenz ist (die wie eine rvalue-Referenz auf einen Typ-Template-Parameter aussieht). In diesem Fall wird stattdessen std::forward verwendet.

Sofern nicht anders angegeben, werden alle Standardbibliotheks-Objekte, von denen verschoben wurde, in einen "gültigen, aber unbestimmten Zustand" versetzt, was bedeutet, dass die Klassen-Invarianten des Objekts gelten (sodass Funktionen ohne Vorbedingungen, wie der Zuweisungsoperator, sicher auf dem Objekt verwendet werden können, nachdem davon verschoben wurde).

std::vector<std::string> v;
std::string str = "example";
v.push_back(std::move(str)); // str is now valid but unspecified
str.back(); // undefined behavior if size() == 0: back() has a precondition !empty()
if (!str.empty())
    str.back(); // OK, empty() has no precondition and back() precondition is met
 
str.clear(); // OK, clear() has no preconditions

Außerdem können die mit xvalue-Argumenten aufgerufenen Standardbibliotheksfunktionen davon ausgehen, dass das Argument die einzige Referenz auf das Objekt ist. Wenn es mit std::move von einem lvalue konstruiert wurde, werden keine Aliasing-Prüfungen durchgeführt. Die Selbst-Move-Zuweisung von Standardbibliotheks-Typen garantiert jedoch, dass das Objekt in einen gültigen (aber normalerweise unbestimmten) Zustand versetzt wird.

std::vector<int> v = {2, 3, 3};
v = std::move(v); // the value of v is unspecified

[bearbeiten] Beispiel

#include <iomanip>
#include <iostream>
#include <string>
#include <utility>
#include <vector>
 
int main()
{
    std::string str = "Salut";
    std::vector<std::string> v;
 
    // uses the push_back(const T&) overload, which means
    // we'll incur the cost of copying str
    v.push_back(str);
    std::cout << "After copy, str is " << std::quoted(str) << '\n';
 
    // uses the rvalue reference push_back(T&&) overload,
    // which means no strings will be copied; instead, the contents
    // of str will be moved into the vector. This is less
    // expensive, but also means str might now be empty.
    v.push_back(std::move(str));
    std::cout << "After move, str is " << std::quoted(str) << '\n';
 
    std::cout << "The contents of the vector are {" << std::quoted(v[0])
              << ", " << std::quoted(v[1]) << "}\n";
}

Mögliche Ausgabe

After copy, str is "Salut"
After move, str is ""
The contents of the vector are {"Salut", "Salut"}

[bearbeiten] Siehe auch

(C++11)
leitet ein Funktionsargument weiter und verwendet das Typ-Template-Argument, um seine Wertkategorie zu erhalten
(Funktionsvorlage) [edit]
konvertiert das Argument in ein xvalue, wenn der Move-Konstruktor nicht wirft
(Funktionsvorlage) [edit]
(C++11)
Verschiebt einen Elementbereich an einen neuen Speicherort
(Funktionstempelat) [edit]