Warum rvalue-Referenzen?



  • Warum wurden für die Movesemantik eigentlich rvalue-Referenzen und neben l- und rvalues auch noch nen ganzen Haufen weiterer -values eingeführt? Hätte es nicht einfach nur einen neuen Qualifizierer gebraucht? Ich nenne ihn mal 'expired', welcher automatisch an temporäre Objekte drangeklatscht wird. Überladung von Kopierkonstruktor und operator=, welche ein 'expired'-qualifiziertes Objekt nehmen, würden doch prima funktionieren. Infolgedessen könnte man sich perfect-forwarding und Universalreferenzen bei Templates sparen. Gab es einen Grund den ich womöglich übersehen habe, wesweshalb das einigermaßen kompliziert wurde?



  • Ich nenne ihn mal 'expired',

    Ob man es 'expired' oder rvalue nennt ist doch wohl egal, oder?

    Aber überleg dir mal, und beschreib uns, wie sich dein 'expired' verhalten soll.

    void foo::consume(expired bar& b)
    {
        m_bars.puch_back(b); // welcher Overload von push_back soll hier aufgerufen werden,
                             // der mit "expired" oder der ohne? Was was wenn wir...
        b.baz();             // ... das Objekt danach nochmal verwenden?
    }
    

    Und dann haben wir noch ein kleines Problem. Die (C++ 98!) Regeln besagen nämlich dass rvalues (*) nicht an non-const Referenzen gebunden werden dürfen. foo::consume könnte also gar nicht ohne weitere Anpassungen der Regeln mit rvalues aufgerufen werden. Also nicht wenn man annimmt dass 'expired' sich so verhalten soll wie 'const'.

    *: Die Unterscheidung zwischen rvalues und lvalues gabes in C++ immer schon, also seit dem ersten Standard. In C++11 wurde das ganze nur etwas genauer definiert und aufgedröselt. Ohne das wäre es nicht möglich gewesen zu einer sinnvollen/praktikablen "move" Lösung zu kommen.

    Aber ich denke du wartest besser auf ne Antwort von Arcoth oder camper. Die können dir das genauer erklären. 🙂



  • ps:

    Techel schrieb:

    Infolgedessen könnte man sich perfect-forwarding und Universalreferenzen bei Templates sparen.

    Wieso sollte man sich das "sparen" wollen?

    Universal-Refs und Perfect-Forwarding sind doch keine zusätzlichen Komplikationen die eingeführt wurden um move zu ermöglichen.

    Sondern im Gegenteil, Perfect-Forwarding ist eine (sehr nützliche) Möglichkeit, die sich aus den neuen Regeln für Referenzen & Templates ergibt. Neue Regeln hätte man für move sowieso gebraucht, und viel einfacher als in C++11 wäre es wohl nicht gegangen. Wieso dann also nicht ein Regel-Set wählen, das neben move auch noch andere nützliche Dinge ermöglicht?


Log in to reply