But why C++ doesn't allow binding lvalue objects to rvalue references?
Assuming you mean "Why doesn't C++ allow binding rvalue references to lvalue objects": it does. It just isn't automatic, so you have to use std::move
to make it explicit.
Why? Because otherwise an innocuous function call can surprisingly destroy something you didn't expect it to:
Class object(much,state,many,members,wow);
looks_safe_to_me(object);
// oh no, it destructively copied my object!
vs.
Class object(much,state,many,members,wow);
obviously_destructive(std::move(object));
// same result, but now the destruction is explicit and expected
A note on destructive copying: why I say destructively and destruction above, I don't mean the object destructor ends its lifetime: just that its internal state has been moved to a new instance. It's still a valid object, but no longer holds the same expensive state it used to.
A note on terminology: let's see if we can clear up the imprecise use of lvalue, rvalue etc. above.
Quoting from cppreference for posterity:
So what actually happens:
- an object exists
- the object is identified locally by an lvalue expression, which cannot be moved from (to protect us from unexpected side-effects)
std::move
yields an xvalue expression (which can be moved from) referring to the same object as the lvalue expression
- this means objects such as variables (which are named by lvalue expressions) cannot be implicitly moved from, and must instead explicitly moved from via an explicit xvalue expression such as
std::move
.
- anonymous temporaries are probably already referred to by prvalue expressions, and can be moved implicitly