What I find interesting is that move semantics silently add something to C++ that did not exist before: invalid objects.
Before, if you created an object, you could design it so that it kept all invariants until it was destroyed. I'd even argue that it is the true core of OOP that you get data structures with guaranteed invariants - a vector or hash map or binary heap never ceases to guarantee its invariants.
But now, you can construct complex objects and then move their data away with std::move() .
What happens with the invariants of these objects?