Pourquoi ce code C ++ 0x n'appelle-t-il pas le constructeur de déplacement?

StackOverflow https://stackoverflow.com/questions/1046801

  •  20-08-2019
  •  | 
  •  

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;
};
Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top