2011-10-28 19 views
14

Digamos que tengo dos vectores y muevo uno hacia el otro, v1 = std::move(v2); ¿estará v2 aún en estado utilizable después de esto?¿El movimiento deja el objeto en un estado utilizable?

+1

Esto parece un duplicado de http://stackoverflow.com/q/7027523/576911. Vea esta respuesta: http://stackoverflow.com/questions/7027523/what-can-i-do-with-a-moved-from-object/7028318#7028318 a esa pregunta que trata las operaciones permitidas en términos de condiciones previas. –

Respuesta

22

De n3290, 17.6.5.15 Movido-de estado de tipos de biblioteca [lib.types.movedfrom]

  1. objetos de tipos definidos en la biblioteca de C++ estándar pueden ser movidos a partir de (12.8) . Las operaciones de movimiento pueden especificarse explícitamente o generarse implícitamente. A menos que se especifique lo contrario, dichos objetos movidos se colocarán en un estado válido pero no especificado.

Dado que el estado es válida, esto significa que puede operar con seguridad en v2 (por ejemplo, mediante la asignación a la misma, lo que pondría de nuevo a un estado conocido). Sin embargo, como no está especificado, significa que no puede confiar en ningún valor particular para v2.empty(), siempre que se encuentre en este estado (pero llamarlo no bloqueará el programa).

Tenga en cuenta que este axioma de semántica de movimiento ("Movido desde objetos se dejan en un estado válido pero no especificado") es algo a lo que todo el código debería aspirar (la mayoría de las veces), no solo los componentes de la Biblioteca estándar. Al igual que la semántica de los constructores de copia debe hacer una copia, pero no se aplica.

+0

+1, pero como está escrito, parece que no se sabe si 'v2' está vacío después de' v2 = std :: vector {}; ' – Gabriel

+0

@Gabriel. Buen punto, una edición está en orden. –

7

No, se deja en un estado no especificado.

Extracto del artículo open-std-org -

.. move() da su objetivo el valor de su argumento, pero es no está obligado a preservar el valor de su fuente. Entonces, para un vector, move() podría razonablemente dejar su argumento como un vector de capacidad cero para evitar tener que copiar todos los elementos. En otras palabras, mover es una lectura potencialmente destructiva.

+7

Se deja en un estado _but válido_ no especificado. Es decir, aún puede usar el objeto de forma que solo tenga la condición previa de que el objeto sea válido. Por ejemplo, puede llamar a vector :: clear() en ese vector movido para ponerlo en un estado conocido, y luego comenzar a insertar objetos en él. – bames53

+3

Es __must__ ser válido. De lo contrario, ¿qué pasaría si el objeto queda fuera del alcance?Lo más probable es que no tenga nada en su almacén de datos, pero sea lo que sea, será válido. – Damon

+1

Hay múltiples niveles (abstractos) de validez. En lo que se refiere al lenguaje, el objeto después de ser movido es válido en la medida en que el objeto aún existe, su destructor puede ser llamado sin causar un comportamiento indefinido, etc. El contrato del objeto, sin embargo, puede ser modificado debido a ser movido . Por ejemplo, el hecho de que un vector se haya convertido en tamaño cero (sin capacidad) es un vector C++ válido, pero un objeto que tiene un método que establece un elemento particular en el vector, sin verificar la suposición (ahora invalidada) de que el vector debe tener un tamaño particular, se convierte en ... – rwong

0

Si desea utilizar v2 después de la mudanza, tendrá que hacer algo como:

v1 = std::move(v2); 
v2.clear(); 

En este punto, v1 tendrá el contenido original de v2 y v2 será en un pozo - estado vacío definido. Esto funciona en todos los contenedores STL (y en las cadenas, para el caso), y si está implementando sus propias clases que admiten la semántica de movimiento, es probable que desee hacer algo similar.

Si su implementación particular del STL en realidad SÍ deja el objeto en un estado vacío, entonces el segundo clear() será esencialmente una operación no operativa. De hecho, si este es el caso, sería una optimización legal para un compilador eliminar el clear() después del movimiento.

Cuestiones relacionadas