粗略地说,右值不应该是“临时变量”,即在表达式结尾处无效吗?
不,他们不是。
鉴于您的 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);
我所说的“某些操作”是“移动”。在两个条件下从一个对象移动是可以的:
- 无论如何它都会消失。IE:暂时的。
- 用户已明确表示要离开它。
这是仅有的两种 r 值引用可以绑定到某物的情况。
r 值引用存在的原因有两个:支持移动语义和支持完美转发(这需要一种新的引用类型,他们可以将时髦的铸造机制挂钩,以及潜在的移动语义)。因此,如果您不执行这两个操作之一,那么使用 a 的原因&&
是值得怀疑的。