Bar*_*rry 12 c++ rvalue-reference c++11
在Scott Meyer的新书中,他提出了rvalue引用限定符的示例用法,如下所示:
class Widget {
private:
DataType values;
public:
DataType& data() & { return values; }
DataType data() && { return std::move(values); } // why DataType?
};
Run Code Online (Sandbox Code Playgroud)
以便:
auto values = makeWidget().data();
Run Code Online (Sandbox Code Playgroud)
移动构造values
而不是复制构造它.
为什么rvalue-ref-qualified data()
返回DataType
而不是DataType&&
?在这种情况下auto
仍会推断DataType
(虽然decltype(auto)
不会 - 但这不是唯一的理由,更喜欢返回一个值而不是ravlue ref).这个高度投票的答案会返回一个rvalue ref,这对我来说在概念上更有意义.
DataType data() && { return std::move(values); } // why DataType?
auto values = makeWidget().data();
Run Code Online (Sandbox Code Playgroud)
保存返回值的临时值将通过move-constructor初始化,从中复制初始化move(values)
.
然后该临时初始化values
,但由于makeWidget().data()
是一个rvalue(精确的prvalue),再次调用move-constructor - 以temporary为参数.
现在考虑copy-elision:
当无名的临时(未绑定到任何引用)将被移动或复制到具有相同cv-nonqualified类型的对象时,将省略复制/移动.构造临时值时,它将直接构建在存储器中,否则将被移动或复制到该存储器中.当无名临时是return语句的参数时,copy elision的这种变体称为RVO,"返回值优化".
所以第二步将(可能)完全省略,只留下一个 - 我们原本应该拥有的那个,返回类型是右值参考.
返回右值引用的问题是如果我们写的话
auto&& values = makeWidget().data();
Run Code Online (Sandbox Code Playgroud)
values
将悬挂作为绑定xvalue到引用不延长任何寿命.当我们返回对象类型时,临时生命周期被延长.