2012-04-18 10 views
8

El siguiente fragmento de código hace que el constructor de copia que se llamará donde esperaba el constructor paso a llamarse:¿Por qué se llama este constructor de copia en lugar de mover el constructor?

#include <cstdio> 

struct Foo 
{ 
    Foo() { puts("Foo gets built!"); } 
    Foo(const Foo& foo) { puts("Foo gets copied!"); } 
    Foo(Foo&& foo) { puts("Foo gets moved!"); } 
}; 

struct Bar { Foo foo; }; 
Bar Meow() { Bar bar; return bar; } 
int main() { Bar bar(Meow()); } 

En VS11 Beta, en modo de depuración, este grabados:

Foo gets built! 
Foo gets copied! 
Foo gets copied! 

he comprobado el estándar y Bar parecen cumplir con todos los requisitos para generar automáticamente un constructor de movimiento predeterminado, pero eso no parece suceder a menos que exista otra razón por la cual no se puede mover el objeto. He visto muchas preguntas relacionadas con mover y copiar constructores por aquí, pero no creo que nadie haya tenido este problema específico.

¿Alguna sugerencia sobre qué está pasando aquí? ¿Es este comportamiento estándar?

+0

¿'return std :: move (bar);' cambia algo? Por cierto, gcc 4.7.0 llama al constructor de movimientos (con copia elision desactivada). –

+0

BTW, gcc 4.6.1 no llama ni a la copia ni al mover el cursor. –

+0

g ++ 4.5.3 solo crea el objeto: "¡Foo se construye!" (elisión de copia), mientras que con copia elisión desactivada copia el objeto dos veces. ¿No se llama solo a un constructor de movimiento cuando tienes un valor r? No estoy del todo seguro de que Meow() califique. –

Respuesta

8

Desafortunadamente, VS11 no proporciona un constructor de movimiento predeterminado. Ver Move Semantics en la sección Comentarios - citar:

A diferencia del constructor de copia por defecto, el compilador no proporciona un movimiento constructor defecto.

+0

Buena captura, gracias! ¿Está eso de alguna manera permitido por el estándar? Si no, supongo que abriré un error en Microsoft Connect, aunque deben ser conscientes de ello. – Trillian

+0

MS simplemente no ha terminado de implementar todas las nuevas características de C++ 11 todavía. Hay más información en http://msdn.microsoft.com/en-us/library/hh409293%28v=vs.110%29.aspx y http://blogs.msdn.com/b/vcblog/archive/2011/ 09/12/10209291.aspx – Fraser

+0

Maldición, ni siquiera estamos obteniendo la generación del constructor de movimientos predeterminado para la versión final VS11: / – Trillian

Cuestiones relacionadas