When, where, and why should we use BigObject&& rv = std::move(big_obj);
?
Short answer: never, nowhere, and for the following reason:
All named variable expressions are lvalues. So what this is doing is taking big_obj
, which is an lvalue, coercing it into an xvalue, and using that to initialize an rvalue reference which can then only be used as an lvalue, and we're back to where we started. It's a completely useless line of code.
Except for function arguments, defining local rvalue references is generally not very useful. They do extend the lifetimes of the temporary objects used to initialize them, though, so they might find occasional use in separating complex expressions across multiple statements.
Value category is a property of expressions, not of references. You choose which kind of reference to use based on the value category of the expressions you want it to be able to bind to. And you use std::move
to force a particular overload of a function to be called where it would otherwise call the wrong one or be ambiguous.
Bjarne's advice given during a Q&A session at GoingNative2013 was basically, don't try to use rvalue references for anything more "clever" than move constructors and move assignment operators.
And from Herb Sutter: A lot of people think move means writing &&
everywhere, but it's not. You don't need to write &&
yourself, unless you're writing a move constructor or move assignment operator, or perfectly forwarding an argument in a function template.