Soy un simple programador. Las variables de mis miembros de clase a menudo consisten en tipos POD y contenedores STL. Debido a esto, rara vez tengo que escribir operadores de asignación o copiar constructores, ya que estos se implementan de forma predeterminada.
Agregue a esto, si uso std::move
en objetos no móviles, utiliza el operador de asignación, lo que significa que std::move
es perfectamente seguro.
Como soy un programador simple, me gustaría aprovechar las capacidades de movimiento sin agregar un constructor de movimiento / operador de asignación a cada clase que escribo, ya que el compilador podría simplemente implementarlos como " this->member1_ = std::move(other.member1_);...
"
Pero no es así (al menos no en Visual 2010), ¿hay alguna razón en particular para esto?
Más importante; ¿Hay alguna forma de evitar esto?
Actualización: si observa la respuesta de GManNickG, proporciona una gran macro para esto. Y si no lo sabía, si implementa la semántica de movimiento, puede eliminar la función de miembro de intercambio.
fuente
MyClass::MyClass(Myclass &&) = default;
?Respuestas:
La generación implícita de constructores de movimientos y operadores de asignación ha sido polémica y ha habido importantes revisiones en borradores recientes del estándar C ++, por lo que los compiladores actualmente disponibles probablemente se comportarán de manera diferente con respecto a la generación implícita.
Para obtener más información sobre la historia del problema, consulte la lista de documentos del WG21 de 2010 y busque "mov"
La especificación actual (N3225, de noviembre) establece (N3225 12.8 / 8):
Hay un lenguaje similar en 12.8 / 22 que especifica cuándo el operador de asignación de movimiento se declara implícitamente como predeterminado. Puede encontrar la lista completa de cambios realizados para respaldar la especificación actual de generación de movimientos implícitos en N3203: Apretar las condiciones para generar movimientos implícitos , que se basó en gran medida en una de las resoluciones propuestas por el artículo N3201 de Bjarne Stroustrup : Avanzar a la derecha .
fuente
cannot be defaulted *in the class body*
. Entonces, definí el destructor afuera y funcionó :). Aunque lo encuentro un poco extraño. ¿Alguien tiene una explicación? El compilador es gcc 4.6.1virtual ~D() = default;
debería funcionar y aún permitir un constructor de movimiento implícito.Los constructores de movimientos generados implícitamente se han considerado para el estándar, pero pueden ser peligrosos. Vea el análisis de Dave Abrahams .
Sin embargo, al final, el estándar incluyó la generación implícita de constructores de movimientos y operadores de asignación de movimientos, aunque con una lista bastante sustancial de limitaciones:
Sin embargo, eso no es todo lo que hay en la historia. Un ctor puede declararse, pero aún así definirse como eliminado:
fuente
Tweak2
. Supongo que tiene algo que ver con el hecho de queNumber
se movería yvector
se copiaría ... pero no estoy seguro: / Entiendo que el problema se propagaría en cascadaTweak3
.Sí, yo también fui por esa ruta. Aquí está su macro:
(Eliminé los comentarios reales, que son extensos y documentales).
Usted especifica las bases y / o miembros de su clase como una lista de preprocesadores, por ejemplo:
Y sale un constructor de movimientos y un operador de asignación de movimientos.
(Aparte, si alguien sabe cómo podría combinar los detalles en una macro, sería genial).
fuente
VS2010 no lo hace porque no eran estándar en el momento de la implementación.
fuente