Cli*_*ton 5 c++ rvalue rvalue-reference c++11
根据我的理解,返回rvalues对函数的引用是危险的原因是由于以下代码:
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());
Run Code Online (Sandbox Code Playgroud)
这留下y了一个未定义的悬空参考.
但是,我不明白为什么上面的代码甚至编译?是否有合理的理由将rvalue引用分配给另一个右值引用?粗略地说,rvalues不应该是"临时",即在表达结束时会变得无效吗?能够分配它们对我来说似乎很愚蠢.
Nic*_*las 10
粗略地说,rvalues不应该是"临时",即在表达结束时会变得无效吗?
不,他们不是.
鉴于您的功能f,这是合法的:
T t{};
T&& y = f(std::move(t));
Run Code Online (Sandbox Code Playgroud)
这是完全有效的C++ 11代码.它也很明确地发生了什么.
您的代码未定义的唯一原因是您传递了一个临时代码.但是r值引用不一定是临时值.
为了进一步详细说明,r值引用在概念上是对某些操作被认为可以执行的值的引用,否则这样做是不可行的.
在C++ 11中非常仔细地指定了R值引用.l值引用可以绑定到任何非临时引用而无需强制转换或任何东西:
T t{};
T &y = t;
Run Code Online (Sandbox Code Playgroud)
r值引用只能隐式绑定到临时或其他"xvalue"(在不久的将来肯定会消失的对象):
T &&x = T{};
T &&no = t; //Fail.
Run Code Online (Sandbox Code Playgroud)
为了将r值引用绑定到非x值,您需要进行显式转换.C++ 11拼写此演员的方式告诉我std::move:
T &&yes = std::move(t);
Run Code Online (Sandbox Code Playgroud)
我所说的"某些操作"是"移动".可以在两个条件下从一个对象移动:
这些是r值引用可以绑定到某些东西的唯一两种情况.
存在r值引用的原因有两个:支持移动语义并支持完美转发(需要一种新的引用类型,它们可以将时髦的转换机制连接到一起,以及可能移动语义).因此,如果你没有做这两个操作中的一个,使用a的原因&&是可疑的.
实际上,我甚至会说参数应该仅&&在两种情况下:转发函数或移动构造函数/赋值.在所有其他情况下,如果要允许移动,则按值输入类型,而不是&&.这样,您可以强制移动作为函数调用的一部分发生.对象可以从那里移动到其最终目的地.
| 归档时间: |
|
| 查看次数: |
3148 次 |
| 最近记录: |