2012-10-29 4 views
32

Was sagt der C++ 11-Standard zur Selbstbewegungszuweisung in Bezug auf die Standardbibliothek? Um konkreter zu sein, was ist, wenn überhaupt, garantiert, was selfAssign tut?Was garantiert die Standardbibliothek für die Selbstbewegung?

template<class T> 
std::vector<T> selfAssign(std::vector<T> v) { 
    v = std::move(v); 
    return v; 
} 
+4

@Mark Ich glaube nicht, dass dies ein Duplikat ist. In dieser Frage geht es darum, selbst zu schreiben. In dieser Frage geht es darum, was die Standardbibliothek garantiert. –

+2

Beachten Sie, dass dies * nicht * die Self-Move-Zuweisung von 'T' beinhaltet. – Xeo

+0

@Xeo Ich habe diese Zeile entfernt. Danke, dass Sie auf den Fehler hingewiesen haben. –

Antwort

31

17.6.4.9 Funktionsargumente [res.on.arguments]

1 Jede der folgenden gilt für alle Argumente an Funktionen definiert in der C++ Standardbibliothek, sofern nicht ausdrücklich anders angegeben.

...

  • Wenn ein Funktionsargument zu einem R-Wert-Referenzparameter bindet, übernehmen die Implementierung kann, dass dieser Parameter auf dieses Argument eine eindeutige Referenz. [Anmerkung: Wenn der Parameter ein generischer Parameter des Formulars T & & ist und ein Wert vom Typ A gebunden ist, bindet das Argument an eine Wertreferenz (14.8.2.1) und ist somit nicht vom vorherigen Satz abgedeckt. - Endnote] [Hinweis: Wenn ein Programm einen Wert von xvalue an eine Bibliotheksfunktion übergibt (z. B. durch Aufruf der Funktion mit dem Argument move (x)), fragt das Programm diese Funktion effektiv an Behandle diesen Wert als temporär. Die Implementierung ist frei, Aliasing-Prüfungen zu optimieren, die möglicherweise benötigt werden, wenn das Argument anlvalue war. -endnote]

So wird die Umsetzung von std::vector<T, A>::operator=(vector&& other) davon ausgehen darf, dass other ein prvalue ist. Und wenn other ein Prvalue ist, ist Self-move-Zuweisung nicht möglich.

Was geschehen ist wahrscheinlich:

v wird in einer Ressource losen Zustand (0 Kapazität) gelassen werden. Wenn v bereits 0 Kapazität hat, dann ist dies ein No-Op.

aktualisieren

Die latest working draft, N4618 deutlich modifiziert wurde, festzustellen, dass in den MoveAssignable Anforderungen der Ausdruck:

t = rv 

(wo rv rvalue ist), t nur der Äquivalenzwert zu sein braucht von rv vor der Zuweisung, wenn t und rv nicht auf dasselbe Objekt verweisen. Und unabhängig, rv Zustand ist nach der Zuweisung nicht angegeben.Es gibt einen zusätzlichen Hinweis für eine weitere Klarstellung:

rv noch die Anforderungen der Bibliothek Komponente erfüllen muss, die ihn verwendet, ob oder ob nicht t und rv auf das gleiche Objekt beziehen.

+4

Wenn ich Ihr Zitat richtig verstehe, ruft die Funktion 'selfAssign' dann undefiniertes Verhalten auf, weil die Voraussetzungen des Zuweisungsoperators nicht erfüllt sind. Mein Verständnis ist, dass "std :: swap" die Zuweisung von sich selbst auf den Aufruf "std :: swap (v, v)" ausführen wird. Ist das ein undefiniertes Verhalten, um 'std :: swap (v, v)' aufzurufen? –

+0

Interessant. Dies würde bedeuten, dass "&&" dann für Argumente "___" bedeutet; Ich frage mich, ob ein Compiler das noch nutzt. –

+1

@MatthieuM .: Das ist nur was der Standard über * eigene * Funktionen sagt; Das ist keine allgemeine Aussage über '&&' Parameter. Sie wären nicht darauf beschränkt, in Code, den Sie schreiben. –

0

Nichts wird passieren. Ein intelligenter Zuweisungsoperator könnte sofort zurückkehren, wenn &other == this. Sonst wird es seine Interna sich selbst zuweisen, nichts tun.

+0

Ja, aber hier sind die Mitglieder des rvalue gleich. Willst du sagen, dass am Ende alles verloren ist? –

+0

Nein, ich mache heute eine schlechte Arbeit beim Lesen von Fragen. Entschuldigen Sie. –

+0

Hoffentlich beantwortet dies Ihre Frage besser. –

Verwandte Themen