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

标签 c++ rvalue-reference dynamic-binding

本题出自C++ Primer(5th Edition),第15章的最后一个话题Simulating Virtual Copy

定义两个继承相关的类:

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只能绑定(bind)到一个右值,std::move(sale)有必要吗?

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

最佳答案

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

判断一个表达式是左值还是右值有复杂的规则。您的示例的相关规则是:

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

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

关于c++ - 关于std::move()在成员重载中的使用问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52125588/

相关文章:

C++ "move from"容器

java - 放置对象类而不是泛型类型

ruby-on-rails - 如何在 Ruby 中使用动态分派(dispatch)调用方法(当方法是模块的一部分时)?

java - 接口(interface)的子类如何被调用

c++ - 仅在res == 0时才使用C++ Curl下载吗?

C++ std:.auto_ptr 或 std::unique_ptr(支持多个编译器,甚至是旧的 C++03 编译器)?

C++ vector 语法错误

c++ - FP 数的指数字段不是我预期的,为什么?

c++ - 重用 "&&" token 作为右值引用背后的基本原理?

c++ - static_cast int 引用 int?