c++ c++11 move-semantics

c++ - Mover constructor en objeto derivado



c++11 move-semantics (2)

Cuando tiene un objeto derivado con un constructor de movimiento, y el objeto base también tiene semántica de movimiento, ¿cuál es la forma correcta de llamar al constructor de movimiento de objeto base desde el constructor de movimiento de objeto derivado?

Intenté lo más obvio primero:

Derived(Derived&& rval) : Base(rval) { }

Sin embargo, esto parece terminar llamando al constructor de copia del objeto Base. Luego traté de usar explícitamente std::move aquí, así:

Derived(Derived&& rval) : Base(std::move(rval)) { }

Esto funcionó, pero estoy confundido por qué es necesario. Pensé que std::move simplemente devuelve una referencia de valor real. Pero como en este ejemplo rval ya es una referencia rvalue, la llamada a std::move debería ser superflua. Pero si no uso std::move aquí, solo llama al constructor de copia. Entonces, ¿por qué es necesario el llamado a std::move ?


Realmente debería usar std :: forward (obj) en lugar de std :: move (obj). Forward devolverá el rvalue o lvalue adecuado en función del obj que es mientras que move cambiará un lvalue a un rvalue.


rval no es un Rvalue. Es un Lvalue dentro del cuerpo del constructor de movimientos. Es por eso que debemos invocar explícitamente a std::move .

Referir this . La nota importante es

Tenga en cuenta que el argumento x se trata como un lvalue interno de las funciones de movimiento, aunque se declara como un parámetro de referencia rvalue. Es por eso que es necesario decir move (x) en lugar de solo x al pasar a la clase base. Esta es una característica clave de seguridad de la semántica de movimientos diseñada para evitar el movimiento accidentalmente dos veces de una variable nombrada. Todos los movimientos ocurren solo a partir de valores r, o con un lanzamiento explícito a rvalue como usar std :: move. Si tiene un nombre para la variable, es un valor l.