Rvalue-Referenz auf Member zurückgeben OK?



  • Angenommen wir haben eine Klasse die einen std::string als Member hat, der von aussen abfragbar ist:

    class Foo {
        std::string m_str;
    
    public:
        std::string const& str() const {
            return m_str;
        }
    };
    

    Fällt euch ein Grund der gegen eine Erweiterung um Rvalue-Referenzen spricht:

    class Foo {
        std::string m_str;
    
    public:
        std::string const& str() const {
            return m_str;
        }
    
        std::string&& str() && { // OK?
            return std::move(m_str);
        }
    };
    

    Oder gibt es hier Fälle wo man mit std::string&& ein Problem bekommen könnte? D.h. wäre es besser/sicherer den std::string by-value herauszumoven?

    (In meinem Konkreten Fall ist es zwar wirklich ein std::string , aber die Frage gilt generell für movable Typen, muss nicht std::string sein.)

    EDIT:
    std::string&& str() const &&
    =>
    std::string&& str() &&


  • Mod

    hustbaer schrieb:

    Fällt euch ein Grund der gegen eine Erweiterung um Rvalue-Referenzen spricht:

    Ja. Dein std::string ist immer noch const-qualifiziert als
    const std::string&&
    und ein Move somit unmöglich. Durch diese Überladung gewinnst du also nichts.



  • Danke.
    War ein copy-paste Fehler. Hab's bereits behoben. Sorry.

    Es geht natürlich um std::string&& str() &&


  • Mod

    In dem Fall sehe keinen schwerwiegenden Grund, der dagegen spricht. Ein direkter Zugriff auf ein Member eines solchen Objektes ist ja auch ein xvalue.
    Dagegen sprechen könnten aus meiner Sicht ggf. in seltenen Fällen 2 Gründe:
    1. Das Interface der Klasse enthält Implementierungsartekfakte (das ist aber im Grunde schon bei einfacher const T&-Rückgabe der Fall).
    2. Ein folgendes Move des Members verletzt möglicherweise Invarianten der Klasse, was mindestens im Fall eines nicht-trivialen Destruktors relevant werden könnte.



  • Ja, der const std::string& -Getter ist bereits vorhanden, vondaher werden keine zusätzlichen Implementierungsdetails nach aussen getragen.

    Was (2) angeht: guter Punkt. Müsste in meinem Fall egal sein, die Klasse hat einen = default Destruktor.


Anmelden zum Antworten