2013-02-04 14 views
15

Betrachten this Code:Haben eingebaute Typen eine Bewegungssemantik?

#include <iostream> 
using namespace std; 

void Func(int&& i) { 
    ++i; 
} 

int main() { 
    int num = 1234; 
    cout << "Before: " << num << endl; 
    Func(std::move(num)); 
    cout << "After: " << num << endl; 
} 

Sein Ausgang ist:

Before: 1234 
After: 1235 

Offensichtlich i innen Func geändert wird, wie es i nachdem sie "umgewandelte" auf einen r-Wert in den Parameter gebunden ist Referenz von std::move.

Nun, mein Punkt:

bedeutet ein Objekt bewegt Eigentum an Ressourcen, von einem Objekt in ein anderes zu übertragen. Die integrierten Typen enthält jedoch keine Ressourcen, da sie selbst die Ressourcen sind. Es macht keinen Sinn, die Ressourcen, die sie besitzen, zu übertragen. Wie im Beispiel gezeigt, wird der Wert num geändert. Seine Ressource, sein Selbst, ist derjenige, der modifiziert wird.

Haben eingebaute Typen Bewegungssemantik?

Auch eingebaute Objekte nach dem Verschieben (wenn es ist) ein wohldefiniertes Verhalten?

+1

Nach was? >> * "Das Verschieben eines Objekts bedeutet die Übertragung des Eigentums an Ressourcen von einem Objekt in ein anderes. Dadurch könnte das ursprüngliche (Quell-) Objekt in einem undefinierten Zustand verbleiben, in dem die Zuweisung die einzige sichere und gültige Operation in diesem Objekt sein könnte. Alle Operationen, die den Inhalt dieser Objekte lesen, können unbestimmte Werte zurückgeben. "* – Nawaz

+0

@Nawaz Laut dem, was ich in SO gelesen habe. –

+3

'std :: move' bewegt sich nicht. Ihr Beispiel hat keine einzige Verschiebung zwischen den Ausgaben. –

Antwort

37

Und so, ist das im Beispiel ein wohldefiniertes Verhalten gezeigt?

Ja, das im Beispiel gezeigte Verhalten ist das einzige vom Standard zugelassene Verhalten. Das liegt daran, dass sich std::move nicht bewegt. Die Dinge, die sich bewegen, sind Bewegungskonstruktoren und Bewegungszuweisungsoperatoren.

Alle std::move does ändert einen lvalue in einen xvalue, sodass er an rvalue-Referenzen gebunden werden kann. Es ruft keinen Konstruktor oder irgendetwas anderes auf. Das Ändern der Wertkategorie erfolgt auf der Typ-Ebene. Nothing passiert zur Laufzeit.

Rvalue-Referenzen sind immer noch Referenzen: Sie beziehen sich auf das ursprüngliche Objekt. Die Funktion inkrementiert die ursprüngliche Ganzzahl um die angegebene Referenz.

Wenn eine Funktion ein Argument als Referenz verwendet, werden keine Kopien oder Bewegungen ausgeführt: Das ursprüngliche Objekt ist an die Referenz gebunden.

Wenn eine Funktion ein Argument nach Wert nimmt, dann können wir eine Verschiebung haben.

Grundlegende Typen haben jedoch keine Move-Konstruktoren. Moves degradieren in diesem Fall zu Kopien.

+2

+1 Schöne Antwort. – Nawaz

Verwandte Themen