2014-09-11 3 views

Antwort

14

In Ihrem Fall returnedStr wird von dem Rückgabewert von GetString(), aber das Rückgabewert von str(1) konstruiert kopier wird bewegen-gebaut werden. Wenn str nicht const wäre, würde der Rückgabewert daraus move-konstruiert werden. Beachten Sie, dass in beiden Fällen die Rückgabewertoptimierung weiterhin anwendbar ist. Der Compiler kann den Rückgabewert (oder sogar str selbst) direkt im Bereich returnedStr konstruieren, wobei er eine oder beide Copy/Move-Konstruktionen überspringt. Dies wird gewährt durch C++ 11 12.8/31:

Wenn bestimmte Kriterien erfüllt sind, wird eine Implementierung erlaubt das Kopieren/Verschieben Bau einer Klasse Objekt zu verzichten, auch wenn das Kopieren/Verschieben Konstruktor und/oder Destruktor für das Objekt haben Nebenwirkungen. In solchen Fällen behandelt die Implementierung die Quelle und das Ziel der ausgelassenen Kopier-/Verschiebungsoperation als einfach zwei verschiedene Arten des Verweises auf das gleiche Objekt, und die Zerstörung dieses Objekts erfolgt zu dem späteren der Zeiten , wenn die beiden Objekte wäre ohne die Optimierung zerstört worden. Diese Auslassung von copy/ Operationen verschieben, Kopie elision genannt, wird in den folgenden Fällen zulässig (die kombiniert werden kann, mehrere Kopien eliminieren):

  • in einer return-Anweisung in einer Funktion mit einer Klasse Rückgabetyp, wenn der Ausdruck der Name eines nichtflüchtigen automatischen Objekts (außer einem Parameter function oder catch-clause) mit demselben cv-unqualifizierten Typ als Rückgabetyp der Funktion ist, kann der Kopier-/Verschiebevorgang weggelassen werden indem man das automatische Objekt direkt in den Rückgabewert der Funktion einbaut

  • ...

  • , wenn ein temporäres Klasse-Objekt, das auf eine Referenz (12.2) nicht würde kopiert/ mit dem gleichen cv-unqualifizierten Typ ein Klassenobjekt bewegte gebunden hat, die Kopie/Verschiebevorgang kann durch Konstruieren des temporäre Objekts direkt in das Ziel der weggelassen Kopie entfallen/

der erste Aufzählungspunkt deckt die elision der Rückgabewerts Konstruktion verschieben, die anderen Abdeckungen bewegen die Rückkehr Wert in returnedStr. Beachten Sie die Anforderung für den gleichen "cv-unqualified" -Typ, was bedeutet, dass dies unabhängig von cv-Qualifikationsmerkmalen funktioniert.


(1) Beachten Sie, dass, wenn wir über eine Klasse X andere als std::string sprachen, eine, die einen Umzug Konstruktor bot eine const X&& nehmen, dann in der Tat der Rückgabewert bewegen würde konstruiert diesen Konstruktor verwenden (was auch immer Semantik könnte es haben).

+0

@PiotrS. Hinzugefügt, obwohl ich glaube nicht, dass die Antwort wirklich eine braucht. Es ist nur eine normale Kopie bei der Arbeit. – Angew

+0

schön, aber ich meine nicht die Anforderungen für ellision, sondern die regelmäßige Rückkehr –

+0

auch, 'X (const X &&);' ist ein * value * Move-Konstruktor, der für oben Beispiel aufgerufen wird, wenn deklariert wird, auch wenn es ist nicht sinnvoll –

6

Die Antwort von Angew ist richtig, aber wer kann sich an alle Sprachanwaltsregeln erinnern?

Um mir zu helfen, es leichter zu erinnern, schrieb ich die folgenden Regeln, die aus dem Mund von STL kamen.

15) nicht den Einheimischen als const zurückkehren [16]

Hemmt $ bewegen Semantik

16) bewegen sich nicht verwenden, wenn sie von Wert genau die gleiche Art lokale Rückkehr [16]

$ NVRO wird nicht verwendet, wenn Sie dies tun.

17) nicht zurück durch Rvalue Referenz (& &) [16]

Es sei denn, Sie wirklich, wirklich $ wissen, was Sie tun.

Hinweise:

[16] Sie Hilfe der Compiler nicht, gehen india 2013 http://www.youtube.com/watch?v=AKtHxKJRwp4

+0

Danke, das ist, wie ich meine Antworten mag :) –

Verwandte Themen