返回值还是右值参考?

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,这对我来说在概念上更有意义.

Col*_*mbo 7

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到引用不延长任何寿命.当我们返回对象类型时,临时生命周期被延长.

  • @LightnessRacesinOrbit引用不是临时引用. (3认同)
  • @Barry [谁应该责备这个范围而不是基于对临时的引用?](http://programmers.stackexchange.com/q/262215); 对于函数参数,我可能错了,因为构造一个例子不是直截了当的.在任何情况下,临时生存至少直到完整表达式结束,因此只有在临时创建范围内定义变量时才会出现问题,也许对于braced-init-lists(IIRC,每个初始化程序都是完整表达式) ). (2认同)