为什么不调用移动分配?
Why is move assignment not called?
#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.
Item getItem()
{
return item;
}
等同于
Item getItem()
{
return this->item;
}
this->item
是数据成员左值。除非您明确表示,否则编译器不会为您移动它。左值仅隐式移动 for some special cases.
解决这个问题的正确方法是提供 ref-qualified 版本的 getItem()
:
Item& getItem() &
{
return this->item;
}
const Item& getItem() const&
{
return this->item;
}
Item getItem() &&
{
return std::move(this->item);
}
然后在你的 main 中使用 std::move
:
int main()
{
ItemHandler ih;
Item it = std::move(ih).getItem();
}
#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.
Item getItem()
{
return item;
}
等同于
Item getItem()
{
return this->item;
}
this->item
是数据成员左值。除非您明确表示,否则编译器不会为您移动它。左值仅隐式移动 for some special cases.
解决这个问题的正确方法是提供 ref-qualified 版本的 getItem()
:
Item& getItem() &
{
return this->item;
}
const Item& getItem() const&
{
return this->item;
}
Item getItem() &&
{
return std::move(this->item);
}
然后在你的 main 中使用 std::move
:
int main()
{
ItemHandler ih;
Item it = std::move(ih).getItem();
}