C++ std::move doesn't move anything: A deep dive into Value Categories
4 months ago
- #Move Semantics
- #Performance Optimization
- #C++
- std::move doesn't actually move anything; it's a cast that changes the value category of an expression to an xvalue (expiring value).
- Move constructors and move assignment operators must be marked noexcept to ensure standard containers use them during reallocation instead of falling back to copying.
- Returning local variables by name enables NRVO (Named Return Value Optimization), which is more efficient than explicitly using std::move in return statements.
- Moving from const objects silently falls back to copying because const objects cannot be modified, which is required for moving resources.
- After moving from an object, it's in a 'valid but unspecified state' and should only be reassigned or destroyed.
- The Rule of Five: If you implement any of the destructor, copy constructor, copy assignment, move constructor, or move assignment, you likely need to implement all five.
- std::forward is used for perfect forwarding in templates, preserving the original value category (lvalue or rvalue) of the argument.
- Small String Optimization (SSO) means moving small strings may still involve copying their inline buffer rather than just swapping pointers.
- Inheritance requires explicit std::move of base class subobjects in derived class move constructors because named rvalue references are treated as lvalues.
- C++17 made copy elision mandatory for prvalues, guaranteeing efficient returns of temporaries without any moves or copies.