...">

When, where, and why should we use "BigObject && rv = std :: move (big_obj);"?

My compiler is the last preview of VC ++ 2013.

#include <utility> struct BigObject { ... }; void f(BigObject&&){} void f(BigObject&) {} void f(BigObject) {} int main() { BigObject big_obj; BigObject& r1 = big_obj; // OK. BigObject&& r2 = big_obj; // error C2440 BigObject&& r3 = std::move(big_obj); // OK. BigObject&& r4 = r3; // error C2440 f(r3); // error C2668: 'f' : ambiguous call to overloaded function } 

When, where and why should we use BigObject&& rv = std::move(big_obj); ?

+4
source share
3 answers

When, where and why should we use BigObject&& rv = std::move(big_obj); ?

Short answer: never, nowhere and for the following reason:

All named variables are lvalues. So, this is what big_obj , which is an lvalue, needs to be done, forcing it to an x ​​value, and using this to initialize the rvalue reference, which then can only be used as an lvalue, and we will return to where we started. This is an absolutely useless line of code.

With the exception of function arguments, defining local rvalue references is usually not very useful. They extend the lifetime of temporary objects used to initialize them, but therefore they can sometimes be used to separate complex expressions into several operators.

Value category is a property of expressions, not references. You choose which link to use depending on the category of expression values ​​to which you want to bind. And you use std::move to force a certain overload of the called function where it would otherwise call it incorrect or would be ambiguous.

The Bjarne recommendations provided during the Q & Session at GoingNative2013 were basically, do not try to use rvalue references for anything smarter than the move and move assignment constructors.

And from Herb Sutter: Many people think that movement means writing && everywhere, but it’s not. You do not need to write && yourself unless you write a move constructor or move an assignment operator or forward an argument in a function template.

+3
source

Sebastian Redl's complementary answer:

First I have to read and understand what is lvalue, rvalue? see here

rvalue, simply said, is the value on the right side of your expression and lvaules on the left.

 int n = 0; // n is a lvalue // 0 is a rvalue 

second you also need to understand what is a link?

links again just talking are (simply) aliases for other variables:

 int& r1 = n; // means r1 ≑ n cout << &r1 << "=" << &n; 

now & says r2 expects r. std::move is a type that converts (if possible) the value of l to the value of r.

you must use move semantics on types that have data stored on the heap and have a move assignment to the constructor. see, for example, std :: vector . if you move the vector to another, the pointer to the data of the moved object will be nullptr or nullptr 'ed.

using move-semantic on a POD is useless, but it won’t harm you, since std :: move is just a throw. what is it equal to the link.

see this little exaple for more.

0
source

Source: https://habr.com/ru/post/1501812/


All Articles