6

据我了解,从函数返回右值引用很危险的原因是由于以下代码:

T&& f(T&& x) { do_something_to_T(x); return static_cast<T&&>(x); }
T f(const T& x) { T x2 = x; do_something_to_T(x2); return x2; }
T&& y = f(T());

这留下y了一个未定义的悬空引用。

但是,我不明白为什么上面的代码甚至可以编译?是否有合理的理由将右值引用分配给另一个右值引用?粗略地说,右值不应该是“临时变量”,即在表达式结尾处无效吗?能够分配它们对我来说似乎很愚蠢。

4

1 回答 1

10

粗略地说,右值不应该是“临时变量”,即在表达式结尾处无效吗?

不,他们不是。

鉴于您的 function f,这同样合法:

T t{};
T&& y = f(std::move(t));

这是完全有效的 C++11 代码。它也明确定义了会发生什么。

您的代码未定义的唯一原因是您传递了一个临时文件。但 r 值引用不必是临时的。

更详细地说,r 值引用在概念上是对某个值的引用,从该值中某些操作被认为可以执行,否则不会可以执行。

R 值引用在 C++11 中非常仔细地指定。左值引用可以绑定到任何非临时对象,而不需要强制转换或任何东西:

T t{};
T &y = t;

r 值引用只能隐式绑定到临时或其他“xvalue”(肯定会在不久的将来消失的对象):

T &&x = T{};
T &&no = t; //Fail.

为了将 r 值引用绑定到非 xvalue,您需要进行显式转换。C ++ 11 拼写这个演员的方式说明std::move

T &&yes = std::move(t);

我所说的“某些操作”是“移动”。在两个条件下从一个对象移动是可以的:

  1. 无论如何它都会消失。IE:暂时的。
  2. 用户已明确表示要离开它。

这是仅有的两种 r 值引用可以绑定到某物的情况。

r 值引用存在的原因有两个:支持移动语义和支持完美转发(这需要一种新的引用类型,他们可以将时髦的铸造机制挂钩,以及潜在的移动语义)。因此,如果您不执行这两个操作之一,那么使用 a 的原因&&是值得怀疑的。

于 2012-02-29T05:39:18.263 回答