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

时间:2018-09-01 06:41:07

标签: c++ rvalue-reference dynamic-binding

此问题来自 C ++ Primer(第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()&&?据我了解,该版本只能在参考限定符&&下的可修改右值(例如时间对象)上运行。可以将std::move(*this)替换为*this吗?

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

在调用add_item的第二版时,该书说:“尽管销售类型是右值引用类型,但销售(像任何其他变量一样)是左值”。但是,如果void add_item(const Quote& sale)是左值,则会调用版本sale。谁可以帮助我?

1 个答案:

答案 0 :(得分:0)

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

有复杂的规则来确定表达式是左值还是右值。您的示例的相关规则是:

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

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