Почему этот код C++0x не вызывает конструктор перемещения?

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

  •  20-08-2019
  •  | 
  •  

Вопрос

По какой-то причине следующий код никогда не вызывает Event::Event(Event&& e)

Event a;
Event b;
Event temp;
temp = move(a);
a = move(b);
b = move(temp);

почему нет?

С использованием std::swap звонит один раз.

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;
};
Это было полезно?

Решение

В вашем коде есть два потенциальных места, где можно ожидать вызова конструктора перемещения (но это не так):

1) вызов std::move
2) во время задания.

Что касается 1), std::move выполняет простое приведение - он не создает объект из копии - если бы это было так, то конструктор перемещения мог бы быть вызван им, но поскольку он выполняет простое приведение rvalue, он не вызывается .Определение std::move аналогично static_cast<Event&&>(temp).

Что касается пункта 2), инициализация и присвоение — это две совершенно разные операции (хотя в некоторых формах инициализации используется символ «=»).Ваш код выполняет присваивание и поэтому использует оператор присваивания по умолчанию, который, как объявлено, принимает ссылку const lvalue.Поскольку вы никогда не инициализируете один объект события другим, вы не увидите вызова конструктора перемещения.Если вы объявили оператор присваивания перемещения: Event& operator=(Event&& other), то ваш текущий код вызовет его или если вы написали: Event a; Event tmp = move(a); ваш конструктор перемещения, как написано, будет вызван.

Другие советы

Вы не используете конструктор перемещения.Я думаю, что swap реализован примерно так

Event a;
Event b;

Event temp(move(a)); // this one wants to use a move constructor
a = move(b);
b = move(temp);

Вы хотите использовать оператор присваивания перемещения, которого нет в вашем коде, поэтому он возвращается к оператору присваивания копирования.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top