Wie bereits in den Kommentaren zur ersten Antwort erwähnt, ist die return std::move(...);
Konstrukt kann in anderen Fällen als der Rückgabe von lokalen Variablen einen Unterschied machen. Hier ist ein runnable Beispiel, das dokumentiert, was passiert, wenn Sie ein Mitgliedsobjekt mit und ohne std::move()
:
#include <iostream>
#include <utility>
struct A {
A() = default;
A(const A&) { std::cout << "A copied\n"; }
A(A&&) { std::cout << "A moved\n"; }
};
class B {
A a;
public:
operator A() const & { std::cout << "B C-value: "; return a; }
operator A() & { std::cout << "B L-value: "; return a; }
operator A() && { std::cout << "B R-value: "; return a; }
};
class C {
A a;
public:
operator A() const & { std::cout << "C C-value: "; return std::move(a); }
operator A() & { std::cout << "C L-value: "; return std::move(a); }
operator A() && { std::cout << "C R-value: "; return std::move(a); }
};
int main() {
// Non-constant L-values
B b;
C c;
A{b}; // B L-value: A copied
A{c}; // C L-value: A moved
// R-values
A{B{}}; // B R-value: A copied
A{C{}}; // C R-value: A moved
// Constant L-values
const B bc;
const C cc;
A{bc}; // B C-value: A copied
A{cc}; // C C-value: A copied
return 0;
}
Vermutlich, return std::move(some_member);
ist nur dann sinnvoll, wenn Sie das betreffende Klassenmitglied tatsächlich verschieben wollen, z. B. in einem Fall, in dem class C
repräsentiert kurzlebige Adapterobjekte mit dem einzigen Zweck, Instanzen von struct A
.
Beachten Sie, wie struct A
bekommt immer kopiert aus class B
auch wenn die class B
Objekt ist ein R-Wert. Das liegt daran, dass der Compiler keine Möglichkeit hat, zu erkennen, dass class B
Instanz von struct A
nicht mehr verwendet werden. Unter class C
verfügt der Compiler über diese Informationen aus std::move()
Deshalb struct A
erhält umgezogen , es sei denn, die Instanz von class C
konstant ist.