Mover objetos en C++ rara vez exige escribir std::move de forma explícita: el propio lenguaje y el compilador ya se encargan en la mayoría de los casos, y recurrir a movimientos manuales solo cuando hace falta produce código más limpio y, en ocasiones, más rápido. La técnica preferible es la elisión de copias, especialmente la optimización del valor de retorno (RVO), que desde C++17 está garantizada cuando se devuelve un objeto temporal creado en la propia sentencia return; con variables locales se obtiene la versión nombrada (NRVO). Cuando la elisión no es posible, el siguiente paso es un movimiento implícito: en expresiones como return val; con un parámetro por valor, el estándar aplica el movimiento automáticamente. Sin embargo, existían dos escenarios con referencias rvalue —devolver el parámetro rvalue por valor o devolver una referencia rvalue— donde antes de C++23 se forzaba una copia o el código no compilaba sin un std::move explícito. En esos casos, la solución pasaba por usar el movimiento manual. A partir de C++23, ambos escenarios generan un movimiento implícito, de modo que sigue siendo válido aplicar la regla de usar std::move solo en situaciones puntuales y dejar que el compilador haga el resto.
Cómo evitar std::move en C++ y aun así mover objetos
Fuentes:
Move in C++ without a std::move
