C++ for Systems Programmers

move semantics and rvalue references

Suppose you are emptying one box into another to move house. Copy semantics says: buy an identical second set of everything and fill the new box (slow, and you now have two of everything). Move semantics says: just pick up the contents from the old box and drop them into the new one, leaving the old box empty (fast, nothing duplicated). When the old box is something you were about to throw away anyway, moving instead of copying is pure win — and that is the whole idea.

The enabling mechanism is the rvalue reference, written with two ampersands, like Widget&&. An ordinary reference Widget& binds to a named object you might still use later (an lvalue). An rvalue reference Widget&& binds to a temporary or to something explicitly marked as expendable — an rvalue — which signals 'this object is about to die, so you may safely steal its insides'. A move constructor or move-assignment takes a Widget&& and, instead of deep-copying, it pilfers the pointers and sizes from the source and then leaves the source in a valid but empty state (so its destructor still runs harmlessly). For a std::vector, a move just transfers the internal buffer pointer — constant time, no element copying.

Why it matters: returning a big vector from a function, growing a container, or passing ownership used to mean expensive copies; move semantics makes those operations cheap, often a few pointer assignments. The crucial honest point: moving from an object does not destroy it — it leaves it in a 'valid but unspecified' state, so you may safely destroy or reassign it but you should not assume what it now holds. And a move is only cheaper than a copy when the type actually implements one; for a plain struct of ints, 'move' is just a copy.

std::vector<int> v = make_big_vector(); std::vector<int> w = std::move(v); // w steals v's buffer; v is now valid-but-empty, no elements copied

Moving a vector is a constant-time pointer transfer; copying it would touch every element.

Common misconception: std::move does not move anything — it is just a cast that marks its argument as an rvalue so a move operation may be selected. If no move constructor exists, the 'moved' object is quietly copied instead, and you pay full price with no warning.

Also called
move constructionrvalue references移動建構右值參考