C ++ 11:为什么允许赋值? [英] C++11: Why is assigning rvalues allowed?

查看:152
本文介绍了C ++ 11:为什么允许赋值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据我的理解,为什么从函数返回右值引用是危险的原因是由于以下代码:

From what I understand the reason why it is dangerous to return rvalues references to from functions is due to the following code:

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 作为未定义的悬挂引用。

This leaves y as an undefined dangling reference.

但是,我不明白为什么上面的代码甚至编译?是否有合理的理由将一个右值引用分配给另一个右值引用?不大概是临时,即在表达式结束时是否会被设置为无效?能够分配他们似乎愚弄我。

However, I don't understand why the above code even compiles? Is there ever a legitimate reason to assign a rvalue reference to another rvalue reference? Aren't rvalues suppose to be, roughly speaking, "temporaries", i.e. going to be made invalid at the end of the expression? Being able to assign them seems silly to me.

推荐答案


不是假设大致是暂时性在表达式结尾处无效?

Aren't rvalues suppose to be, roughly speaking, "temporaries", i.e. going to be made invalid at the end of the expression?

不,他们不是。

给定您的函数 f ,这是合法的:

Given your function f, this is just as legal:

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

这是完全有效的C ++ 11代码。

This is perfectly valid C++11 code. And it's also well-defined what happens.

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

The only reason your code is undefined is because you pass a temporary. But r-value references don't have to be temporaries.

为了进一步阐述,r值引用概念上是对某个值的引用,某些操作

To elaborate a bit more, an r-value reference conceptually is a reference to a value from which certain operations are considered OK to do, which would not otherwise be OK to do.

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

R-value references are very carefully specified in C++11. An l-value reference can be bound to any non-temporary without the need for a cast or anything:

T t{};
T &y = t;

r值引用只能以隐式其他xvalue(最近肯定会在不久的将来消失的对象):

An r-value reference can only be implicitly bound to a temporary or other "xvalue" (an object that is most certainly going to go away in the near future):

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

为了将r值引用绑定到非xvalue,投。 C ++ 11拼写这个演员的方式是: std :: move

In order to bind an r-value reference to a non-xvalue, you need to do an explicit cast. The way C++11 spells this cast is telling: std::move:

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

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

The "certain operations" I was speaking of was "moving". It is OK to move from an object under exactly two conditions:


  1. 它会消失。 IE:暂时。

  2. 用户已明确表示要从中移动。

这些是r值引用可以绑定到某些东西的唯一两种情况。

And these are the only two cases where an r-value reference can bind to something.

r值引用存在两个原因:支持移动语义和支持完美的转发(需要一个新的引用类型,他们可以钩挂有趣的铸造力学,以及潜在的移动语义)。因此,如果你不执行这两个操作之一,使用&& 的原因是可疑的。

There are exactly two reasons r-value references exist: to support move semantics and to support perfect forwarding (which required a new reference type that they could hook funky casting mechanics onto, as well as potentially move semantics). Therefore, if you're not doing one of these two operations, the reasons to use a && are dubious.

的确,我甚至会说,只有两种情况下参数应该&& :转发函数或者移动构造函数/分配。在所有其他情况下,如果您要允许移动,您可以按而不是&& 键入类型。这样,你强制移动发生作为函数调用的一部分。该对象可以从那里移动到其最终目的地。

Indeed, I would even go so far as to say that parameters should be && in only two cases: a forwarding function, or a move constructor/assignment. In all other cases, if you want to allow movement, you take the type by value, not by &&. That way, you force the move to happen as part of the function call. The object can be moved from there into its final destination.

这篇关于C ++ 11:为什么允许赋值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆