beginpluses
beginpluses

Reputation: 537

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.

Upvotes: 5

Views: 173

Answers (1)

Howard Hinnant
Howard Hinnant

Reputation: 219345

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.

Upvotes: 13

Related Questions