c++ visual-c++ c++11 visual-studio-2012 move-semantics

c++ - ¿Puede un constructor de movimiento estar implícito?



visual-c++ c++11 (2)

Considera la siguiente clase:

class A { public: std::string field_a; std::string field_b; }

Ahora considere la siguiente construcción de copia:

A a1(a2);

La construcción de copias copiará adecuadamente A pesar de la falta de un constructor de copia explícito porque los constructores de copia para std::string serán llamados por el constructor de copia implícita generado por el compilador.

Lo que deseo saber es, ¿es lo mismo para la construcción de movimientos?

EDITAR : las pruebas aquí muestran que:

A a2(std::move(a1));

En realidad resultará en una construcción de copia, a menos que el constructor de movimiento específico:

A( A && other ) : a(std::move(other.a)) {}

Se define.

EDITAR EDITAR Señalé a Stephan T Lavavej y le pregunté por qué VC 2012 no parece seguir lo que dice el borrador 12.8 sobre la generación implícita de constructores de movimientos. Él tuvo la amabilidad de explicar:

Es más una "característica aún no implementada" que un error. VC actualmente implementa lo que yo denomino referencias rvalue v2.0, donde los ctors / asignaciones de movimiento nunca se generan implícitamente y nunca afectan la generación implícita de copiadores / asignadores. C ++ 11 especifica las referencias rvalue v3.0, que son las reglas que estás viendo.


El compilador sintetiza un constructor de movimiento si puede y si no hay un constructor de copia definido por el usuario. La restricción de que no se sintetiza ningún constructor de movimiento si hay un constructor de copia está destinada a evitar la ruptura del código existente. Por supuesto, todos los miembros deben ser móviles. Las reglas exactas son un poco más complicadas.


Sí, del borrador de C ++ 11, 12.8:

Si la definición de una clase X no declara explícitamente un constructor de movimiento, se declarará implícitamente como predeterminado si y solo si

  • X no tiene un constructor de copia declarado por el usuario,
  • X no tiene un operador de asignación de copia declarado por el usuario,
  • X no tiene un operador de asignación de movimiento declarado por el usuario,
  • X no tiene un destructor declarado por el usuario, y
  • el constructor de movimiento no se definiría implícitamente como eliminado.

La última condición se especifica con más detalle más adelante:

Un constructor de copia / movimiento implícitamente declarado es un miembro público en línea de su clase. Un constructor de copia / movimiento predeterminado para una clase X se define como eliminado (8.4.3) si X tiene:

  • un miembro de variante con un constructor correspondiente no trivial y X es una clase similar a unión,
  • un miembro de datos no estáticos del tipo de clase M (o matriz del mismo) que no se puede copiar / mover porque la resolución de sobrecarga (13.3), aplicada al constructor correspondiente de M, resulta en una ambigüedad o una función que se elimina o inaccesible del predeterminado constructor,
  • una clase base B directa o virtual que no se puede copiar / mover porque la resolución de sobrecarga (13.3), aplicada al constructor correspondiente de B, da como resultado una ambigüedad o una función que se elimina o no se puede acceder desde el constructor predeterminado.
  • cualquier clase base directa o virtual o miembro de datos no estáticos de un tipo con un destructor que se elimina o inaccesible del constructor predeterminado,
  • para el constructor de copias, un miembro de datos no estáticos del tipo de referencia rvalue, o
  • para el constructor de movimiento, un miembro de datos no estático o una clase base directa o virtual con un tipo que no tiene un constructor de movimiento y no se puede copiar trivialmente.

Hablando claro, el constructor de movimientos se declarará implícitamente si:

  1. La clase no tiene ninguna de las otras funciones especiales miembro declaradas por el usuario.
  2. El constructor de movimientos se puede implementar con sensatez moviendo todos sus miembros y bases.

Su clase obviamente cumple con estas condiciones.