tags:

views:

502

answers:

2

For some reason, the following code never calls Event::Event(Event&& e)

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

why not?

Using std::swap calls it once.

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;
};
+5  A: 

Your code has two potential locations for where one may expect the move constructor to get called (but it doesn't):

1) calling std::move
2) during assignment.

Regarding 1), std::move does a simple cast - it does not create an object from a copy - if it did then the move constructor might get invoked by it, but since it does a simple rvalue cast it doesn't get invoked. The definition of std::move is similar to static_cast<Event&&>(temp).

Regarding 2), Initialization and assignment are two entirely different operations (even though some forms of initialization use the '=' symbol). Your code does assignment and therefore uses the default assignment operator which is declared to accept a const lvalue reference. Since you never initialize one event object with another, you won't see your move constructor get invoked. If you declared a move assignment operator: Event& operator=(Event&& other), then your current code would invoke it or if you wrote: Event a; Event tmp = move(a); your move constructor, as written, would get invoked.

Faisal Vali
Thanks!(marked as answer because yours was first)
Neil G
+7  A: 

You are not using the move constructor. I think swap is implemented something like this

Event a;
Event b;

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

You want to use the move assignment operator, which doesn't exist in your code, so it falls back to the copy assignment operator.

Johannes Schaub - litb