| One useful rule of thumb that works 99% of the time in C++11 is: Never use "std::move" It's really just there to allow fancy optimisations and you don't need it in most cases.
You should rely on the sane defaults instead: - Putting variables on the stack to manage object ownership/lifetime is a good default. - Use std::unique_ptr or std::shared_ptr() for heap ownership (single ownership vs. shared) - For a non-owning (mutable) reference, use const & (&) or const * (*) when the value may not exist. - Always prefer passing by value (return types and parameters) - If a parameter type is heavy, take a (const) reference. - If the return type is heavy, the compiler's RVO will do its job. No need to be more fancy than this |
Essentially you use std::move when you want to have pointer semantics without using a pointer. You don't want to use a pointers sometimes to keep objects on stack and use it to track ownership.
So instead of doing C* c1 = new C; C* c2 = c1; You have C c1; C c2 = c1; // here I have a move constructor which moves c1 to c2, c2 is now a null object.
This is what rust is able to do and you don't need expensive atomics (shared_ptr), ugly template syntax (unique_ptr), can keep everything on the stack and (!) have the objects be automatically cleaned up correctly.