2012-04-18 14 views
8

Il seguente frammento di codice fa sì che il costruttore di copia per essere chiamato in cui mi aspettavo il costruttore mossa per essere chiamato:Perché viene chiamato questo costruttore di copia anziché il costruttore di mosse?

#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()); } 

Su VS11 Beta, in modalità debug, questa stampa:

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

ho controllato lo standard e Bar sembrano soddisfare tutti i requisiti per generare automaticamente un costruttore di mosse predefinito, ma ciò non sembra avvenire a meno che non ci sia un altro motivo per cui l'oggetto non possa essere spostato. Ho visto molte domande relative alla costruzione e alla copia del costruttore qui intorno, ma non credo che nessuno abbia avuto questo problema specifico.

Qualsiasi suggerimento su cosa sta succedendo qui? Questo comportamento standard è?

+0

Fa 'return std :: move (bar);' cambia qualcosa? BTW, gcc 4.7.0 chiama il costruttore di movimento (con copia elision disattivata). –

+0

BTW, gcc 4.6.1 non chiama né la copia né lo spostamento. –

+0

g ++ 4.5.3 crea solo l'oggetto: "Foo gets built!" (copia elisione), mentre con copia elettronica disabilitata copia l'oggetto due volte. Il costruttore di movimenti non è chiamato solo quando hai un valore? Non sono del tutto sicuro che Meow() si qualifichi. –

risposta

8

Sfortunatamente, VS11 non fornisce un costruttore di spostamento predefinito. Vedere Move Semantics nella sezione Osservazioni - per citare:

Diversamente il costruttore di copia di default, il compilatore non fornisce un costruttore mossa default.

+0

Bella cattura, grazie! È in qualche modo consentito dallo standard? Altrimenti suppongo che aprirò un bug su Microsoft Connect, anche se devono esserne ben consapevoli. – Trillian

+0

MS non ha ancora completato l'implementazione di tutte le nuove funzionalità di C++ 11. Sono disponibili maggiori informazioni all'indirizzo http://msdn.microsoft.com/en-us/library/hh409293%28v=vs.110%29.aspx e http://blogs.msdn.com/b/vcblog/archive/2011/ 09/12/10209291.aspx – Fraser

+0

Dannazione, non abbiamo ancora ottenuto la generazione predefinita del costruttore di spostamenti per la versione finale di VS11: / – Trillian

Problemi correlati