si prega di guardare il seguente codice di esempio:Perché viene chiamato il costruttore della copia invece del costruttore di movimento?
#include <iostream>
struct Foo {
Foo() { std::cout << "Default!\n"; }
Foo(const Foo& foo) { std::cout << "Copy!\n"; }
Foo(Foo&& foo) { std::cout << "Move!\n"; }
};
struct Bar {
Foo foo;
Bar() {}
Bar(Bar &that) : foo(that.foo) {}
Bar(Bar &&that) : foo(std::move(that.foo)) {}
};
Bar f() {
Bar bar;
return bar;
}
int main() {
Bar bar(f());
}
I'am aspettava che l'uscita di questo codice dovrebbe essere:
Default!
Move!
ma quello che ottengo è:
Default!
Copy!
Non riesco a vedere alcun motivo per cui venga chiamato il costruttore di copia anziché il costruttore di mosse. Se inserisco la parola chiave const
davanti a Bar &that
nella dichiarazione del costruttore di copie di struct Bar
, ho ottenuto il risultato corretto. So che è meglio per molti casi prendere un riferimento a lvalue piuttosto che un semplice riferimento a lvalue per i costruttori di copie, ma voglio solo sapere il motivo per cui ciò è accaduto.
Perché in questo esempio è stato preferito Bar &
su Bar &&
anche se il valore di ritorno di f()
deve essere considerato come un valore di prvalore? Perché la parola chiave const
risolve il problema? const
risolve davvero il problema? Ha qualcosa a che fare con RVO (Return Value Optimization)? Oppure, questo è solo un bug del compilatore?
Ho testato questo esempio su Visual C++ novembre 2012 CTP.
ho trovato un problema simile qui:
Copy constructor is being called instead of the move constructor
Ma ancora non riesco a capire perché.
Qualcuno può aiutarmi?
Impossibile riprodurre. Con GCC ho appena ottenuto "Default!" (Sano NRVO al lavoro), con '-fno-elide-constructors' ottengo l'atteso' Default! Mossa! Spostare! '. Forse un compilatore b^Hshortcoming? –
cambia 'Bar (Bar & that)' a 'Bar (const bar & that)'. –
@ KerrekSB 1. Capisco il caso di NRVO. Ma perché due piuttosto che un solo "Move!" È previsto quando la copia elision è disattivata? 2. Quindi stai dicendo che questo è solo un bug del compilatore che ho usato? Grazie comunque. –