是否有RValue Reference(&&)的返回有用的情况?

当一个函数应该返回一个RValue引用时是否有一个原因? 技巧,技巧,成语或模式?

MyClass&& func( ... ); 

我知道一般返回引用的危险,但有时候我们也是这么做的,难道我们( T& T::operator=(T)只是一个习惯用法的例子)。 但是T&& func(...)怎么样? 我们可以从中获益吗? 当你编写库或API代码时,与仅仅客户端代码相比,可能会有所不同?

在适当的时候有几次,但是比较less见。 在一个例子中,当你想允许客户端从一个数据成员移动的情况下。 例如:

 template <class Iter> class move_iterator { private: Iter i_; public: ... value_type&& operator*() const {return std::move(*i_);} ... }; 

这跟随了towi的评论。 你永远不想返回对本地variables的引用。 但是你可能会有这样的:

 vector<N> operator+(const vector<N>& x1, const vector<N>& x2) { vector<N> x3 = x1; x3 += x2; return x3; } vector<N>&& operator+(const vector<N>& x1, vector<N>&& x2) { x2 += x1; return std::move(x2); } vector<N>&& operator+(vector<N>&& x1, const vector<N>& x2) { x1 += x2; return std::move(x1); } vector<N>&& operator+(vector<N>&& x1, vector<N>&& x2) { x1 += x2; return std::move(x1); } 

除非两个参数都是左值,否则这应该防止所有情况下的副本(和可能的分配)。

不,只要返回值。 一般情况下返回引用并不是一件危险的事 – 它返回引用局部variables是危险的。 然而,返回一个右值引用几乎在所有情况下都是毫无价值的(我想如果你正在编写std::move或者什么的话)。

你可以通过引用返回,如果你确定被引用的对象在函数退出后不会超出范围,例如它是全局对象的引用,或者成员函数返回对类字段的引用等。

这个返回的引用规则与左值和右值引用相同。 不同的是你想如何使用返回的引用。 我可以看到,右值引用返回是很less见的。 如果你有function:

 Type&& func(); 

你不会喜欢这样的代码:

 Type&& ref_a = func(); 

因为它有效地将ref_a定义为Type&,因为指定的右值引用是一个左值,并且在这里不会执行实际的移动。 这很像:

 const Type& ref_a = func(); 

除了实际的ref_a是一个非const的左值引用。

而且,即使直接将func()传递给另一个带有Type &&参数的函数,它也不是非常有用,因为它仍然是该函数中的一个命名引用。

 void anotherFunc(Type&& t) { // t is a named reference } anotherFunc(func()); 

func()和anotherFunc()的关系更像func()同意anotherFunc()可能拥有的(或者你可以说“窃取”)从func()返回的对象的“授权”。 但是这个协议很松散。 调用者仍然可以“非const”左值引用“被盗”。 实际上函数很less定义为右值引用参数。 最常见的情况是“anotherFunc”是一个类名,anotherFunc()实际上是一个移动构造函数。

还有一种可能的情况:当你需要解压缩一个元组并将值传递给一个函数。

在这种情况下,如果你不确定copy-elision,这可能是有用的。

这样一个例子:

 template<typename ... Args> class store_args{ public: std::tuple<Args...> args; template<typename Functor, size_t ... Indices> decltype(auto) apply_helper(Functor &&f, std::integer_sequence<size_t, Indices...>&&){ return std::move(f(std::forward<Args>(std::get<Indices>(args))...)); } template<typename Functor> auto apply(Functor &&f){ return apply_helper(std::move(f), std::make_index_sequence<sizeof...(Args)>{}); } }; 

除非你正在编写某种forms的std::bindstd::threadreplace,否则很less见的情况。