为什么这个C++ 0x代码不会调用移动构造函数?

Nei*_*l G 4 c++ c++11

出于某种原因,以下代码从不调用 Event::Event(Event&& e)

Event a;
Event b;
Event temp;
temp = move(a);
a = move(b);
b = move(temp);
Run Code Online (Sandbox Code Playgroud)

为什么不?

使用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;
};
Run Code Online (Sandbox Code Playgroud)

Joh*_*itb 11

您没有使用移动构造函数.我认为交换是这样实现的

Event a;
Event b;

Event temp(move(a)); // this one wants to use a move constructor
a = move(b);
b = move(temp);
Run Code Online (Sandbox Code Playgroud)

您希望使用移动赋值运算符,该运算符在代码中不存在,因此它将回退到复制赋值运算符.


Fai*_*ali 10

您的代码有两个可能的位置,可以指望移动构造函数被调用(但它没有):

1)
在赋值期间调用std :: move 2).

关于1),std :: move做一个简单的强制转换 - 它不会从副本创建一个对象 - 如果它做了,那么移动构造函数可能会被它调用,但是因为它做了一个简单的右值转换,所以它不会被调用.std :: move的定义类似于static_cast<Event&&>(temp).

关于2),初始化和赋值是两个完全不同的操作(即使某些形式的初始化使用'='符号).您的代码执行赋值,因此使用声明为接受const左值引用的默认赋值运算符.由于您永远不会使用另一个事件对象初始化一个事件对象,因此您不会看到您的移动构造函数被调用.如果你声明了一个移动赋值运算符:Event& operator=(Event&& other),那么你当前的代码会调用它,或者如果你写了:Event a; Event tmp = move(a);你的移动构造函数将被调用.