Frage

Eine der coolen neuen Funktionen des kommenden C ++ - Standards C ++ 0x sind "RValue -Referenzen". Eine RValue -Referenz ähnelt einer lvalue (normalen) Referenz, mit der Ausnahme, dass sie an einen temporären Wert gebunden werden kann const Referenz):

void FunctionWithLValueRef(int& a) {...}
void FunctionWithRValueRef(int&& a) {...}

int main() {
     FunctionWithLValueRef(5); // error, 5 is a temporary
     FunctionWithRValueRef(5); // okay
}

Warum haben sie also einen völlig neuen Typ erfunden, anstatt einfach die Einschränkungen für normale Referenzen aufzuheben, um die Bindung an Provisorien zu ermöglichen?

War es hilfreich?

Lösung

Es wäre sinnlos.Sie würden das Ding in der Funktion ändern und die Änderung würde sofort verloren gehen, da das Ding eigentlich nur vorübergehend ist.

Der Grund für den neuen Typ liegt in der Notwendigkeit, entscheiden zu können, was tatsächlich ein R-Wert ist und was nicht.Nur dann kann man sie tatsächlich für die coolen Dinge verwenden, für die sie verwendet werden.

string toupper(string && s) { // for nonconst rvalues
    for(char &c : s) make_uppercase(c);
    return move(s); // move s into a returned string object
}

string toupper(string const& s) { // for the rest
    // calls the rvalue reference version, by passing 
    // an rvalue copy.
    return toupper(string(s));
}

Wenn Sie nun einen R-Wert haben und ihn an toupper übergeben, kann der R-Wert direkt geändert werden, da wir wissen, dass der temporäre Wert sowieso wegwerfbar ist, sodass wir ihn auch einfach ändern können und ihn nicht kopieren müssen.Dieselbe Beobachtung wird auch für die sogenannten Bewegungskonstruktoren und Bewegungszuweisungen verwendet.Die rechte Seite wird nicht kopiert, sondern ihre Sachen werden einfach gestohlen und dorthin verschoben *this.

Wenn Sie sagen würden, dass R-Werte an nicht konstante L-Wert-Referenzen binden können, dann hätten Sie keine Möglichkeit herauszufinden, ob dies letztendlich auf einen L-Wert (benanntes Objekt) oder einen R-Wert (temporär) verweist.


Es ist wahrscheinlich weniger bekannt, aber trotzdem nützlich: Sie können L-Wert- oder R-Wert-Ref-Qualifizierer in eine Mitgliedsfunktion einfügen.Hier ist ein Beispiel, das die bestehende Semantik von R-Wert-Referenzen natürlich auf den impliziten Objektparameter erweitert:

struct string {
    string& operator=(string const& other) & { /* ... */ }
};

Jetzt kann man es nicht mehr sagen

string() = "hello";

Was verwirrend ist und meistens keinen Sinn ergibt.Was zum & Das Obige besagt, dass der Zuweisungsoperator nur für L-Werte aufgerufen werden kann.Dasselbe kann für R-Werte durch Setzen erfolgen &&.

Andere Tipps

Da eine neue Art von Referenz Hinzufügen können Sie zwei Überlastungen eines Verfahrens schreiben:

void CopyFrom(MyClass &&c)
{
    dataMember.swap(c);
}

void CopyFrom(const MyClass &c)
{
    dataMember.copyTheHardWay(c);
}

Die Version, die die neue Art Referenz akzeptiert darf die Variable ändern sie erhält, weil diese Variable nicht anderswo verwendet werden soll. So kann es „stehlen“ den Inhalt davon.

Das ist der ganze Grund, warum diese Funktion hinzugefügt wurde; eine Art von Referenz beibehalten würde das angestrebte Ziel nicht erreichen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top