Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why not define rvalue reference to be rvalue expression?

Let's consider the following code:

class X {
    std::vector<int> _v;
public:
    X(std::vector<int>&& v): _v(std::move(v)) {}
};

The compiler calls this constructor only for objects that can be moved. So why not just define an rvalue references to be rvalue expressions and don't write every time std::move for them?

The ctor member initialization list would look like:

_v(v)

But this would still be a move, not a copy.

like image 668
beginpluses Avatar asked Jun 30 '19 18:06

beginpluses


People also ask

Is an rvalue reference an rvalue?

An rvalue reference behaves just like an lvalue reference except that it can bind to a temporary (an rvalue), whereas you can not bind a (non const) lvalue reference to an rvalue.

What is the point of rvalue reference?

Rvalue references enable you to write one version of a function that accepts arbitrary arguments. Then that function can forward them to another function as if the other function had been called directly.

Can you modify an rvalue?

rvalue references have two properties that are useful: rvalue references extend the lifespan of the temporary object to which they are assigned. Non-const rvalue references allow you to modify the rvalue.

Can lvalue reference bind rvalue?

An lvalue reference can bind to an lvalue, but not to an rvalue.


1 Answers

While it is somewhat unfortunate to require the std::move in this common case, it was believed that an implicit move causing a run-time error in a few cases would be more harmful.

For example:

class Y
{
public:
    Y(const std::vector<int>& v);
};

class X {
    std::vector<int> v_;
    Y                y_;
public:
    X(std::vector<int>&& v): v_(v), y_(v) {}
};

In this modified example the constructor of X uses v twice. If the first use of v implicitly moved, then the second use of v would quite likely not be getting the expected value.

Thus to avoid the accidental "use after move", if it has a name, then it can be used more than once, and is thus safer to treat it as an lvalue.

like image 157
Howard Hinnant Avatar answered Nov 15 '22 10:11

Howard Hinnant