关于在成员重载中使用 std::move() 的问题

Question about the usage of std::move() in member overloading

本文关键字:move 问题 std 成员 重载      更新时间:2023-10-16

这个问题来自C++入门(第5版(,这是第15章的最后一个主题模拟虚拟副本

定义两个按继承相关的分类:

class Quote{
public:
virtual Quote* clone() const & {return new Quote(*this);}
virtual Quote* clone() && {return new Quote(std::move(*this));}
//other members
};
class Bulk_quote: public Quote{
public:
Bulk_quote* clone() const& {return new Bulk_quote(*this);}
Bulk_quote* clone() && {return new Bulk_quote(std::move(*this));}
//other members
};

以及雇用他们的班级:

class {
public:
void add_item(const Quote& sale)   //copy the given object
{ items.insert(std::shared_ptr<Quote>(sale.clone()));}
void add_item(Quote&& sale)  //move the given object
{items.insert(std::shared_ptr<Quote>(std::move(sale).clone()));}
//other memebers
private:
static bool compare(const std::shared_ptr<Quote>& lhs,const std::shared_ptr<Quote>& rhs)
{return lhs->isbn() < rhs->isbn();}
std::multiset<std::shared_ptr<Quote>,decltype(compare)*> items(compare);
};

我陷入了两个观察:

(1( 为什么std::move(*this)成员virtual Quote* clone()&&的定义?据我了解,这个版本只能在引用限定符&&下的可修改的 rvalue(例如,时间对象(上运行。std::move(*this)可以被*this取代吗?

(2(与(1(类似,为什么在第二个定义中std::move(sale)成员add_item只能在右值对象上运行。对于右值引用Quote&& sale只能绑定到右值,std::move(sale)必要吗?

对于调用add_item的第二个版本,该书说"虽然销售类型是右值引用类型,但销售(像任何其他变量一样(是左值"。但是,如果 verisonvoid add_item(const Quote& sale)是左值,则将调用sale。谁能帮助我?

您似乎将对象与表达式混淆了。值类别(左值或右值(是表达式的属性,而不是对象的属性,因此,例如,即使*this引用临时对象,它作为表达式仍然是左值。sale也是如此。

确定表达式是左值还是右值需要复杂的规则。示例的相关规则如下:

  • 形式*expr的表达式始终是左值;

  • 作为表达式的变量的非限定名始终是左值。