Pourquoi ce code C ++ 0x n'appelle-t-il pas le constructeur de déplacement?
Question
Pour une raison quelconque, le code suivant n'appelle jamais Event::Event(Event&& e)
Event a;
Event b;
Event temp;
temp = move(a);
a = move(b);
b = move(temp);
pourquoi pas?
Utiliser std::swap
l’appelle une fois.
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;
};
La solution
Votre code a deux emplacements potentiels pour indiquer où le constructeur du déplacement doit être appelé (mais ce n'est pas le cas):
1) appelant std :: move
2) en cours d'affectation.
En ce qui concerne 1), std :: move effectue un transtypage simple - il ne crée pas d'objet à partir d'une copie. Si c'est le cas, le constructeur du déplacement peut être invoqué par celui-ci, mais comme il le fait avec une simple conversion de valeur, il ne le fait pas. t être invoqué. La définition de std :: move est similaire à static_cast<Event&&>(temp)
.
En ce qui concerne 2), l’initialisation et l’assignation sont deux opérations totalement différentes (même si certaines formes d’initialisation utilisent le symbole '='). Votre code fait une affectation et utilise donc l'opérateur d'affectation par défaut qui est déclaré accepter une référence const lvalue. Etant donné que vous n'initialisez jamais un objet d'événement avec un autre, vous ne verrez pas votre constructeur de déplacement être appelé. Si vous avez déclaré un opérateur d'affectation de déplacement: Event& operator=(Event&& other)
, votre code actuel l'appellerait ou si vous écriviez: Event a; Event tmp = move(a);
votre constructeur de déplacement, tel qu'il est écrit, serait appelé.
Autres conseils
Vous n'utilisez pas le constructeur de déménagement. Je pense que swap est mis en œuvre quelque chose comme ceci
Event a;
Event b;
Event temp(move(a)); // this one wants to use a move constructor
a = move(b);
b = move(temp);
Vous souhaitez utiliser l'opérateur d'attribution de déplacement, qui n'existe pas dans votre code, il revient donc à l'opérateur d'attribution de copie.