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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With