mardi 3 novembre 2020

Returning by value or by rvalue reference from rvalue reference qualified member function?

In Effective Modern C++, Item 12, Scott Meyers writes the following class to show how useful overloading member functions on the reference qualifiers can be:

class Widget {
public:
    using DataType = std::vector<double>;
    …
    DataType& data() &            // for lvalue Widgets
    { return values; }            // return lvalue

    DataType data() &&            // for rvalue Widgets
    { return std::move(values); } // return rvalue
    …
private:
    DataType values;
};

This seems clear: now non_temp_obj.data() will call the first overload and return a reference to a member of an object which is still alive afterwards, whereas make_temp_obj().data() returns by value a member of an object which dies as soon as that expression is done.

Here's my first question: as regards the && overload, why return std::move(values); and not just return values;, considering we are returning by value?

In the errata, however, Meyers writes

A better way to have the rvalue reference overload of the data member function return an rvalue is to have it return an rvalue reference. That would avoid the creation of a temporary object for the return value, and it would be consistent with the by-reference return of the original data interface near the top of page 84.

which I interpret as suggesting to change

    DataType data() &&
    { return std::move(values); }

to

    DataType&& data() &&
    { return std::move(values); }

but I don't understand the reason, especially in light of this answer which pretty much convinces me that the book version is corrected and the errata is wrong.

So my second question is: who's right?

Aucun commentaire:

Enregistrer un commentaire