在Effective Modern C++的第 12 条中,Scott Meyers 编写了以下类来展示在引用限定符上重载成员函数是多么有用:
class Widget {
public:
using DataType = std::vector<double>;
…
DataType& data() & // for lvalue Widgets
{ return values; } // return lvalue
DataType data() && // for rvalue Widgets
{ return std::move(values); } // return rvalue
…
private:
DataType values;
};
这似乎很清楚: nownon_temp_obj.data()
将调用第一个重载并返回对之后仍然存在的对象成员的引用,而make_temp_obj().data()
通过值返回对象的成员,该成员在该表达式完成后立即死亡。
这是我的第一个问题:关于&&
重载,考虑到我们按值返回,为什么return std::move(values);
不只是?return values;
然而,在勘误表中,迈耶斯写道
让成员函数的右值引用重载
data
返回一个右值的更好方法是让它返回一个右值引用。这将避免为返回值创建临时对象,并且与data
第 84 页顶部附近的原始接口的按引用返回一致。
我解释为建议改变
DataType data() &&
{ return std::move(values); }
到
DataType&& data() &&
{ return std::move(values); }
但我不明白原因,特别是鉴于这个答案几乎让我相信这本书的版本是正确的,而勘误表是错误的。
所以我的第二个问题是:谁是对的?