为什么不调用移动分配?

问题描述 投票:2回答:1
#include <iostream>

using namespace std;

struct Item
{
  Item () {cout << "Item constructor called." << endl;}
  ~Item () {cout << "Item destructor called." << endl;}
  Item (const Item& item): x(item.x) {cout << "Item copy constructor called." << endl;}
  Item (Item&& item) : x(std::move(item.x)) {cout << "Item move constructor called." << endl;}
  Item& operator=(const Item& item) { x= item.x; cout << "Item assignment operator called." << endl; return *this;}
  Item& operator=(Item&& item) { x= std::move(item.x); cout << "Item move assignment operator called." << endl; return *this;}

  int x = 0;
};

struct ItemHandler
{
    Item getItem() 
    {
      cout << "getItem called."<< endl; 
      return item;
    }

    Item item{}; 
};

int main()
{
  ItemHandler ih;  
  cout << "trying move assignment" << endl;
  Item&& it = ih.getItem();
}

我期待,因为ih.getItem()将创建一个副本,然后移动分配给它。但这是我得到的输出:

Item constructor called.
trying move assignment
getItem called.
Item copy constructor called.
Item destructor called.
Item destructor called.
c++11 move-semantics
1个回答
1
投票
Item getItem() 
{
    return item;
}

相当于

Item getItem() 
{
    return this->item;
}

this->item是数据成员左值。除非您明确说明,否则编译器不会为您移动它。 Lvalues只隐式移动for some special cases


解决此问题的正确方法是提供getItem()的ref-qualified版本:

Item& getItem() &   
{
    return this->item;
}

const Item& getItem() const&
{
    return this->item;
}

Item getItem() &&
{
    return std::move(this->item);
}

然后在你的主要使用std::move

int main()
{
    ItemHandler ih;  
    Item it = std::move(ih).getItem();
}
© www.soinside.com 2019 - 2024. All rights reserved.