Perché questo codice C ++ 0x non chiama il costruttore di spostamento?
Domanda
Per qualche motivo, il seguente codice non chiama mai Event::Event(Event&& e)
Event a;
Event b;
Event temp;
temp = move(a);
a = move(b);
b = move(temp);
perché no?
L'utilizzo di std::swap
lo chiama una volta.
class Event {
public:
Event(): myTime(0.0), myNode(NULL) {}
Event(fpreal t, Node* n);
Event(Event&& other);
Event(Event const& other) = delete;
~Event();
bool operator<(Event const& other) const { return myTime < other.myTime; }
bool operator>(Event const& other) const { return myTime > other.myTime; }
fpreal getTime() const { return myTime; }
void setTime(fpreal time) { myTime = time; }
Node* getNode() const { return myNode; }
private:
fpreal myTime;
Node* myNode;
};
Soluzione
Il tuo codice ha due potenziali posizioni in cui ci si può aspettare che venga chiamato il costruttore di mosse (ma non lo fa):
1) chiamando std :: move
2) durante l'incarico.
Riguardo a 1), std :: move fa un semplice cast - non crea un oggetto da una copia - se lo facesse allora il costruttore di mosse potrebbe essere invocato da esso, ma poiché fa un semplice rvalue cast non lo fa ' non essere invocato. La definizione di std :: move è simile a static_cast<Event&&>(temp)
.
Per quanto riguarda 2), l'inizializzazione e l'assegnazione sono due operazioni completamente diverse (anche se alcune forme di inizializzazione usano il simbolo '='). Il codice esegue l'assegnazione e pertanto utilizza l'operatore di assegnazione predefinito che viene dichiarato accettare un riferimento al valore costante. Dato che non inizializzi mai un oggetto evento con un altro, non vedrai il tuo costruttore di mosse essere invocato. Se dichiarassi un operatore di assegnazione di spostamenti: Event& operator=(Event&& other)
, il tuo codice attuale lo invocherebbe o se scrivessi: Event a; Event tmp = move(a);
il costruttore di spostamenti, come scritto, verrebbe invocato.
Altri suggerimenti
Non stai usando il costruttore di mosse. Penso che lo swap sia implementato in questo modo
Event a;
Event b;
Event temp(move(a)); // this one wants to use a move constructor
a = move(b);
b = move(temp);
Si desidera utilizzare l'operatore di assegnazione degli spostamenti, che non esiste nel codice, quindi ricade sull'operatore di assegnazione delle copie.