【问题标题】:Why doesn't this C++0x code call the move constructor?为什么这个 C++0x 代码不调用移动构造函数?
【发布时间】:2010-11-06 00:24:53
【问题描述】:

由于某种原因,以下代码从不调用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;
};

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

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

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

    您想使用代码中不存在的移动赋值运算符,因此它回退到复制赋值运算符。

    【讨论】:

      【解决方案2】:

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

      1) 调用 std::move
      2)在分配期间。

      关于 1),std::move 做了一个简单的转换——它不会从一个副本创建一个对象——如果它这样做了,那么移动构造函数可能会被它调用,但是因为它做了一个简单的右值转换,所以它不会'不会被调用。 std::move 的定义类似于static_cast&lt;Event&amp;&amp;&gt;(temp)

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

      【讨论】:

        猜你喜欢
        • 2012-04-29
        • 1970-01-01
        • 2013-04-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-04
        • 2022-07-06
        • 1970-01-01
        相关资源
        最近更新 更多