En C ++ 11, se introdujo la “semántica de movimiento”, implementada a través de dos miembros especiales: constructor de movimiento y asignación de movimiento. Ambas operaciones dejan el movido desde objeto construido.
¿No hubiera sido mejor dejar la fuente en un estado destruido? ¿No es lo único que puedes hacer con un objeto movido es destruirlo de todos modos?
Howard Hinant
En el “universo de las operaciones de movimiento” hay cuatro posibilidades:
target source
is is left
----------------------------------------------------------
constructed <-- constructed // C++11 -- move construction
constructed <-- destructed
assigned <-- constructed // C++11 -- move assignment
assigned <-- destructed
Cada una de estas operaciones es ¡útil! std::vector<T>::insert
solo podría hacer uso de los tres primeros. Aunque tenga en cuenta:
- La fuente de la 2.ª y la 4.ª no debe tener una duración de almacenamiento automático, estático o de subprocesos. La duración del almacenamiento de la fuente debe ser dinámica, de lo contrario, el compilador llamará al destructor en el objeto ya destruido. Y no, el compilador no puede (en general) rastrear si un objeto se ha movido:
X x1, x2;
if (sometimes)
{
x1 = std::move(x2);
}
// Is x2 moved-from here?
-
El 2.º y el 4.º pueden ser emulados por el 1.º y el 3.º respectivamente, simplemente llamando manualmente al destructor en la fuente después de la operación.
-
El primero y el tercero son cruciales. Algoritmos como
std::swap
ystd::sort
regularmente necesitan ambas operaciones. Estos algoritmos no necesitan destruir ninguno de sus objetos de entrada, solo cambiar sus valores.
Armado con este conocimiento, en el período 2001-2002 enfoqué mis esfuerzos en las dos operaciones que dejaron su fuente construida porque estas dos operaciones tendrían el mayor impacto (positivo) en lo que entonces era C++98. En ese momento supe que si no reducía las ambiciones de este proyecto, nunca tendría éxito. Incluso reducido, estaba en el límite demasiado ambicioso para tener éxito.
Esta restricción se reconoce en la propuesta original de semántica de movimiento en la sección titulada “Semántica de movimiento destructivo”.
Al final, simplemente nos dimos por vencidos en esto como demasiado dolor para no ganar lo suficiente. Sin embargo, la propuesta actual no prohíbe la semántica de movimientos destructivos en el futuro. Podría hacerse además de la semántica de movimiento no destructiva descrita en esta propuesta si alguien desea llevar esa antorcha.
Para obtener más detalles sobre lo que se puede hacer con un objeto movido, consulte https://stackoverflow.com/a/7028318/576911
-
Hay una propuesta de C++1z para un movimiento destructivo, motivado por problemas de cero.
– Yakk – Adam Nevraumont
1 de noviembre de 2015 a las 17:26
-
@Yakk-AdamNevraumont, ¿tiene algún enlace sobre esta propuesta? Quiero algunos detalles sobre el movimiento destructivo.
– usuario2269707
30 de noviembre de 2018 a las 2:34
-
@Yakk-AdamNevraumont: ¿Enlace?
– einpoklum
12 oct 2019 a las 21:13
-
Howard, ¿ha habido alguna actividad en los últimos años con respecto a movimientos destructivos?
– einpoklum
17 de julio de 2020 a las 19:20
-
Sí, pero no lo he estado siguiendo de cerca. Pero no existe actividad sin papel. Y todos los documentos se pueden encontrar aquí: open-std.org/jtc1/sc22/wg21/docs/papers
– Howard Hinant
17 de julio de 2020 a las 19:27
“¿No es lo único que puedes hacer con un objeto movido es destruirlo de todos modos?” Estilísticamente, sí. Técnicamente, puedes mover otro objeto hacia él.
– edmz
31/10/2015 a las 18:43