Antworten:
Beta_ab&&
Beta::toAB() const {
return move(Beta_ab(1, 1));
}
Dies gibt eine baumelnde Referenz zurück, genau wie beim lvalue-Referenzfall. Nachdem die Funktion zurückgekehrt ist, wird das temporäre Objekt zerstört. Sie sollten Beta_ab
nach Wert wie folgt zurückgeben
Beta_ab
Beta::toAB() const {
return Beta_ab(1, 1);
}
Jetzt wird ein temporäres Beta_ab
Objekt ordnungsgemäß in den Rückgabewert der Funktion verschoben. Wenn der Compiler dies kann, wird er die Verschiebung mithilfe von RVO (Rückgabewertoptimierung) vollständig vermeiden. Jetzt können Sie Folgendes tun
Beta_ab ab = others.toAB();
Und es wird das temporäre Konstrukt verschieben ab
oder RVO ausführen, um das Verschieben oder Kopieren ganz zu unterlassen. Ich empfehle Ihnen, BoostCon09 Rvalue References 101 zu lesen , in dem die Angelegenheit erklärt wird und wie (N) RVO damit interagiert.
In anderen Fällen wäre es eine gute Idee, eine rvalue-Referenz zurückzugeben. Stellen Sie sich vor, Sie haben eine getAB()
Funktion, die Sie häufig vorübergehend aufrufen. Es ist nicht optimal, eine konstante Wertreferenz für rwertige Provisorien zurückzugeben. Sie können es so implementieren
struct Beta {
Beta_ab ab;
Beta_ab const& getAB() const& { return ab; }
Beta_ab && getAB() && { return move(ab); }
};
Beachten Sie, dass dies move
in diesem Fall nicht optional ist, da ab
es sich weder um einen lokalen automatischen noch um einen temporären Wert handelt. Das ref-Qualifikationsmerkmal &&
besagt nun, dass die zweite Funktion für rvalue-Temporäre aufgerufen wird, wobei anstelle des Kopierens der folgende Schritt ausgeführt wird
Beta_ab ab = Beta().getAB();
Es kann zum Beispiel in einem etwas anderen Kontext effizienter sein:
template <typename T>
T&& min_(T&& a, T &&b) {
return std::move(a < b? a: b);
}
int main() {
const std::string s = min_(std::string("A"), std::string("B"));
fprintf(stderr, "min: %s\n", s.c_str());
return 0;
}
Als interessante Beobachtung clang++ -O3
generiert mein Computer 54 Anweisungen für den obigen Code gegenüber 62 Anweisungen für den regulären Code std::min
. Damit werden jedoch -O0
518 Anweisungen für den obigen Code generiert, gegenüber 481 für reguläre std::min
.
for(:)
freigegebenen Objekt verwendet und dieses integriert. Fix: ideone.com/tQVOal
std::move()
wird nur als explizite Besetzung verwendet, um den Punkt klarer zu veranschaulichen. Es ist kein Code, den Sie kopieren und in Ihr Projekt einfügen würden. Dies widerspricht nicht der Antwort mit der höchsten Abstimmung, da dort ein temporäres Objekt innerhalb der Funktion erstellt wird. Hier ist das zurückgegebene Objekt eines der Argumente (temporäre Objekte werden als letzter Schritt bei der Bewertung des vollständigen Ausdrucks zerstört, der (lexikalisch) den Punkt enthält, an dem sie erstellt wurden).