[c++0x] Frage zu R-Value-Referenzen



  • Hi,
    ich hatte ungefähr folgenden Code:

    //Expr : std::string
        std::size_t found = Expr.find(it->Representation());
        while( found != std::string::npos )
        {
        [...]
            Expr.erase(0,found + it->Representation().length());
        [...]
        found = Expr.find(it->Representation());
    }
    

    In kurzen Abständen also drei Aufrufe um die immer gleiche Representation zu bekommen, die sich im ausgelassenen Code aber nicht ändert.
    Meine erster Gedanke war eine objektkonstante Referenz zu nutzen, sprich:

    const std::string& Rep = it->Representation()
    

    Da ich aber mit gcc 4.5.1 arbeite und eh schon dabei bin so viel wie möglich vom neuen Standard zu nutzen, dachte ich mir, dass man für diesen Fall evtl. R-Value-Referenzen nutzen könnte:

    std::string&& Rep = it->Representation();
        std::size_t found = Expr.find(Rep);
        while( found != std::string::npos )
        {
        [...]
            Expr.erase(0,found + Rep.length());
        [...]
        found = Expr.find(Rep);
    

    So lange Situationerklärung, aber kurze Frage: Ist es in Ordnung eine R-Value-Referenz mehrfach zu nutzen, wie in meinem Fall getan oder ist dies riskant, da ein R-Value ja signalisiert, dass der Inhalt gefahrlos "weggenommen" werden kann? Oder würdet ihr für so etwas doch wieder zu objektkonstanten Referenzen greifen?

    Gruß Gate



  • Gate schrieb:

    std::string&& Rep = it->Representation();
    

    Ich nehme mal an, dass der Rückgabetyp der Funktion std::string ist. In dem Fall macht es keinen Unterschied, ob Du
    std::string&& Rep = it->Representation();
    oder
    std::string Rep = it->Representation();
    schreibst. Du kannst das mit der Rvalue-Referenz also gleich bleiben lassen.

    In erster Linie sind sie dazu da, effiziente Klassen zu schreiben. std::string wird in C++0x neben dem Copy-Konstruktor einen Move-Konstruktor bekommen, der eine Rvalue-Referenz entgegen nimmt. In "normalem" Benutzercode wird die Rvalue-Referenz wohl weniger auftauchen. Es ist eher ein Werkzeug für Klassen- und Bibliotheks-Autoren.

    Gate schrieb:

    So lange Situationerklärung, aber kurze Frage: Ist es in Ordnung eine R-Value-Referenz mehrfach zu nutzen, wie in meinem Fall getan oder ist dies riskant, da ein R-Value ja signalisiert, dass der Inhalt gefahrlos "weggenommen" werden kann?

    Hier hast Du eine benannte Rvalue Referenz. Die Verwendung des Namens in Ausdrücken stellt einen Lvalue-Ausdruck dar:

    void sink(int&);  // #1 akzeptiert nur Lvalues
    void sink(int&&); // #2 akzeptiert nur Rvalues
    
    int   prvalue(); // Pure Rvalue  \ beides fasst man unter
    int&&  xvalue(); // Xvalue       / Rvalues zusammen
    int&   lvalue();
    
    void demo(int&& rref)
    {
      sink(prvalue()); // ruft #2 auf
      sink( xvalue()); // ruft #2 auf
      sink( lvalue()); // ruft #1 auf
    
      int j = 1729
      int& lref = j;
      sink(j);    // ruft #1 auf
      sink(lref); // ruft #1 auf
      sink(rref); // ruft #1 auf <-- !!!
    }
    

    Unbenannte Rvalue-Referenzen sind Xvalues (gehören zu den Rvalue-Ausdrücken).
    Benannte Rvalue-Referenzen sind Lvalues.

    kk



  • Vielen Dank für deine wiedermal einleuchtende Antwort. In das Thema werde ich mich noch etwas reinfuchsen müssen.

    Gruß Gate


Anmelden zum Antworten