I disagree with you opinion on that. If you don't understand something doesn't mean that this is just for fancy optimizations.
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.
> If you don't understand something doesn't mean that this is just for fancy optimizations.
You should definitely understand it, but if you find yourself wanting to use it, you should start by considering alternatives first. It's a sharp (and often unsafe) tool that should be avoided in most cases.
For your example, unique_ptr is the correct (and safe) solution and will do the same thing.
> you don't need expensive atomics (shared_ptr)
Note that shared_ptr provides no "atomicity". It is in reality exceptionally cheap.
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.