- C++ moves are not destructive (as compared to move semantics in Rust). This means that types must arrange for a valid "moved-from" state. This isn't a huge issue if the type has a natural sentinel value, but not all types have one and I often end up wrapping class members in std::optional to arrange for one. Frankly, this is annoying, because I now have to pay the overhead of std::optional for no good reason (and also use a C++17 compiler, which is not always available).
- the syntax for rvalue references and perfect forwarding references is the same, which is the cause for much confusion, especially among beginners. I happily used move semantics for a year before I realized that rvalue references and perfect forwarding references are distinct concepts.