关于std::move()在成员重载中的使用问题
Question about the usage of std::move() in member overloading
本题来自C++ Primer(5th Edition),最后一题模拟虚拟副本 在第 15 章中。
定义两个通过继承相关的 classed:
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 雇用他们:
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) 为什么要在成员 virtual Quote* clone()&&
的定义中使用 std::move(*this)
?据我了解,此版本只能在引用限定符 &&
下的可修改右值(例如,时间对象)上 运行。可以 std::move(*this)
替换为 *this
吗?
(2)与(1)类似,为什么成员add_item
的第二个定义中的std::move(sale)
只能是右值对象上的运行。对于右值引用 Quote&& sale
只能绑定到一个右值,是否需要 std::move(sale)
?
为了调用第二版add_item
,书上说"although the type of sale is an rvalue reference type, sale(like any other variable) is an lvalue"。但是,如果 sale
是左值,则将调用版本 void add_item(const Quote& sale)
。谁能帮帮我?
您似乎混淆了对象和表达式。值类别(左值或右值)是表达式的 属性,而不是对象的,因此即使 *this
引用临时对象,它 作为表达式 仍然是左值。 sale
.
也是
确定表达式是左值还是右值有复杂的规则。您的示例的相关规则是:
*expr
形式的表达式始终是左值;
作为表达式的变量的非限定名称始终是左值。
本题来自C++ Primer(5th Edition),最后一题模拟虚拟副本 在第 15 章中。
定义两个通过继承相关的 classed:
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 雇用他们:
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) 为什么要在成员 virtual Quote* clone()&&
的定义中使用 std::move(*this)
?据我了解,此版本只能在引用限定符 &&
下的可修改右值(例如,时间对象)上 运行。可以 std::move(*this)
替换为 *this
吗?
(2)与(1)类似,为什么成员add_item
的第二个定义中的std::move(sale)
只能是右值对象上的运行。对于右值引用 Quote&& sale
只能绑定到一个右值,是否需要 std::move(sale)
?
为了调用第二版add_item
,书上说"although the type of sale is an rvalue reference type, sale(like any other variable) is an lvalue"。但是,如果 sale
是左值,则将调用版本 void add_item(const Quote& sale)
。谁能帮帮我?
您似乎混淆了对象和表达式。值类别(左值或右值)是表达式的 属性,而不是对象的,因此即使 *this
引用临时对象,它 作为表达式 仍然是左值。 sale
.
确定表达式是左值还是右值有复杂的规则。您的示例的相关规则是:
*expr
形式的表达式始终是左值;作为表达式的变量的非限定名称始终是左值。