1. You must implement a move constructor or a move assignment operator in order for std::move to do anything
2. The moved object could be left in an unusable state, depending on your implementation, after stealing its internal resources.
1. You must implement a move constructor or a move assignment operator in order for std::move to do anything
2. The moved object could be left in an unusable state, depending on your implementation, after stealing its internal resources.
This was a difficult mental hurdle to get over with Rust, but once you do, move semantics make a lot more sense.
edit: When I said everything is move by default, I mean everything that isn't "Copy", such as integers, floats, etc.
Yes, you should avoid the manual memory management that necessitates writing them. But work with a team of developers fresh out of school and next thing you know your codebase will be brimming with this kind of busywork.
Bit of a nitpick, but there are sometimes other functions with overloads for rvalue references to move the contents out - think something like std::optional's `value() &&`. And you don't necessarily need to implement those move constructor/assignment functions yourself, typically the compiler generated functions are what you want (i.e. the rule of 5 or 0)
The "proper" semantics are that it leaves the object in a valid but unspecified state. So, invariants still hold, you can call functions on it, or assign to it.
Only functions with no preconditions, unless the type makes more guarantees as to the moved-from state.
So, you can do things like check if a moved from std::vector is empty (often the case in practice), then start appending elements to it.