¿Qué es std::move() y cuándo debería usarse?

Resuelto Basilevs asked hace 14 años • 9 respuestas
  1. ¿Qué es?
  2. ¿Qué hace?
  3. ¿Cuándo debería usarse?

Se agradecen buenos enlaces.

Basilevs avatar Aug 05 '10 16:08 Basilevs
Aceptado

1. "¿Qué es?"

Aunque std::move() técnicamente es una función, yo diría que en realidad no es una función . Es una especie de conversor entre las formas en que el compilador considera el valor de una expresión.

2. "¿Qué hace?"

Lo primero que hay que tener en cuenta es que std::move() en realidad no mueve nada . Cambia una expresión de ser un valor l (como una variable con nombre) a un valor x . Un valor x le dice al compilador:

Puedes saquearme, mover cualquier cosa que tenga y usarla en otro lugar (ya que de todos modos seré destruido pronto)".

en otras palabras, cuando usas std::move(x), estás permitiendo que el compilador canibalice x. Por lo tanto, si xtiene, digamos, su propio búfer en la memoria, después de std::move()ejecutar el compilador, puede hacer que otro objeto sea propietario.

También puedes moverte de un valor pr (como un valor temporal que estás pasando), pero esto rara vez es útil.

3. "¿Cuándo se debe utilizar?"

Otra forma de hacer esta pregunta es "¿Para qué canibalizaría los recursos de un objeto existente?" bueno, si estás escribiendo código de aplicación, probablemente no estarás jugando mucho con los objetos temporales creados por el compilador. Básicamente, haría esto en lugares como constructores, métodos de operador, funciones similares a algoritmos de biblioteca estándar, etc., donde los objetos se crean y destruyen automáticamente de forma frecuente. Por supuesto, eso es sólo una regla general.

Un uso típico es "mover" recursos de un objeto a otro en lugar de copiarlos. @Guillaume enlaza a esta página que tiene un breve ejemplo sencillo: intercambiar dos objetos con menos copia.

template <class T>
swap(T& a, T& b) {
    T tmp(a);   // we've made a second copy of a
    a = b;      // we've made a second copy of b (and discarded a copy of a)
    b = tmp;    // we've made a second copy of tmp (and discarded a copy of b)
}

usar move te permite intercambiar los recursos en lugar de copiarlos:

template <class T>
swap(T& a, T& b) {
    T tmp(std::move(a));
    a = std::move(b);   
    b = std::move(tmp);
}

Piense en lo que sucede cuando Tes, digamos, vector<int>de tamaño n. En la primera versión lees y escribes 3*n elementos, en la segunda versión básicamente lees y escribes solo los 3 punteros a los búferes de los vectores, más los tamaños de los 3 búferes. Por supuesto, la clase Tnecesita saber cómo hacer el movimiento; su clase debe tener un operador de asignación de movimiento y un constructor de movimiento para la clase Tpara que esto funcione.

einpoklum avatar Nov 19 '2014 20:11 einpoklum

Página de Wikipedia sobre referencias de valores R de C++ 11 y constructores de movimientos

  1. En C++11, además de los constructores de copia, los objetos pueden tener constructores de movimiento.
    (Y además de copiar operadores de asignación, tienen operadores de asignación de movimiento).
  2. El constructor de movimiento se utiliza en lugar del constructor de copia, si el objeto tiene el tipo "rvalue-reference" ( Type &&).
  3. std::move()es una conversión que produce una referencia de valor a un objeto, para permitir moverse desde él.

Es una nueva forma en C++ de evitar copias. Por ejemplo, al usar un constructor de movimiento, a std::vectorpodría simplemente copiar su puntero interno a los datos al nuevo objeto, dejando el objeto movido en un estado movido desde y, por lo tanto, sin copiar todos los datos. Esto sería válido para C++.

Intente buscar en Google semántica de movimientos, rvalue, reenvío perfecto.

Scharron avatar Aug 05 '2010 09:08 Scharron