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