Reputation: 537
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
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