Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

In Scott Meyer's new book, he proposes an example usage for rvalue reference qualifiers that looks something like this:

class Widget {
private:
    DataType values;

public:
    DataType& data() &  { return values; } 
    DataType  data() && { return std::move(values); } // why DataType?
};

So that:

auto values = makeWidget().data();

move-constructs values instead of copy-constructing it.

Why does the rvalue-ref-qualified data() return DataType instead of DataType&&? auto would still deduce DataType in that case (although decltype(auto) wouldn't - but that can't be the only reason to prefer to return a value instead of an ravlue ref). This highly voted answer returns an rvalue ref, which makes more sense conceptually to me.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
327 views
Welcome To Ask or Share your Answers For Others

1 Answer

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

auto values = makeWidget().data();

The temporary that holds the return value will be initialized through the move-constructor, copy-initialized from move(values).

Then that temporary initializes values, but since makeWidget().data() is an rvalue (prvalue to be precise) the move-constructor is called again - with the temporary as its argument.

Now consider copy-elision:

When a nameless temporary, not bound to any references, would be moved or copied into an object of the same cv-unqualified type, the copy/move is omitted. When that temporary is constructed, it is constructed directly in the storage where it would otherwise be moved or copied to. When the nameless temporary is the argument of a return statement, this variant of copy elision is known as RVO, "return value optimization".

So the second move will (presumably) be completely elided, and only one is left - the one we would have had anyway, had the return type been the rvalue reference.

The problem with returning an rvalue reference is that if we write

auto&& values = makeWidget().data();

values will be dangling as binding an xvalue to a reference doesn't extend anythings lifetime. When we return the object type, the temporaries lifetime is extended.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...