为什么++ i被认为是一个l值,但i ++不是? [英] Why is ++i considered an l-value, but i++ is not?

查看:139
本文介绍了为什么++ i被认为是一个l值,但i ++不是?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么++ i是l值?和i ++不

Why is ++i is l-value? and i++ not

最初有两个问题,一个被删除,因为那是完全重复。因此,不要向下投票回答之前和之后增量之间的差异。

Initially there were 2 questions one was removed since that was exact duplicate. So don't down vote the answers that were answering difference between pre- and post-increment.

推荐答案

已经知道 ++ i 是一个左值的原因是将它传递给引用。

Well as another answerer pointed out already the reason why ++i is an lvalue is to pass it to a reference.

int v = 0;
int const & rcv = ++v; // would work if ++v is an rvalue too
int & rv = ++v; // would not work if ++v is an rvalue

第二个规则的原因是允许当引用是对const的引用时,使用文字来初始化引用:

The reason for the second rule is to allow to initialize a reference using a literal, when the reference is a reference to const:

void taking_refc(int const& v);
taking_refc(10); // valid, 10 is an rvalue though!

为什么我们要介绍一个右值。好,这些术语在为这两种情况构建语言规则时出现:

Why do we introduce an rvalue at all you may ask. Well, these terms come up when building the language rules for these two situations:


  • 我们想要一个定位器值。这将表示包含可以读取的值的位置。

  • 我们要表示表达式的值。

上述两点取自C99标准,其中包括这个很好的脚注:

The above two points are taken from the C99 Standard which includes this nice footnote quite helpful:


[名称lvalue最初来自赋值表达式E1 =
E2中的
,其中左操作数E1是
需要是(可修改)左值。
也许更好的考虑为
表示一个对象定位器
值。有时被称为
''rvalue''在这个国际
标准描述为'
的价值表达式''。 ]

[ The name ‘‘lvalue’’ comes originally from the assignment expression E1 = E2, in which the left operand E1 is required to be a (modifiable) lvalue. It is perhaps better considered as representing an object ‘‘locator value’’. What is sometimes called ‘‘rvalue’’ is in this International Standard described as the ‘‘value of an expression’’. ]

定位器值称为 lvalue ,而评估该位置产生的值称为 rvalue 。这也是正确的,根据C ++标准(谈论左值到右值的转换):

The locator value is called lvalue, while the value resulting from evaluating that location is called rvalue. That's right according also to the C++ Standard (talking about the lvalue-to-rvalue conversion):


4.1 / 2:由左值指示的对象
是右值
结果。

4.1/2: The value contained in the object indicated by the lvalue is the rvalue result.



结论



使用上面的语义,很清楚为什么 i ++ 不是左值,而是右值。因为返回的表达式不再位于 i 中(它增加了!),它只是可能感兴趣的值。修改 i ++ 返回的值将没有意义,因为我们没有可以再次读取该值的位置。所以标准说它是一个右值,因此它只能绑定到一个引用到const。

Conclusion

Using the above semantics, it is clear now why i++ is no lvalue but an rvalue. Because the expression returned is not located in i anymore (it's incremented!), it is just the value that can be of interest. Modifying that value returned by i++ would make not sense, because we don't have a location from which we could read that value again. And so the Standard says it is an rvalue, and it thus can only bind to a reference-to-const.

但是,在对照中, ++ i 返回的表达式是 i 。像在 int a = ++ i; 中一样,提取一个左值到右值的转换将读取它的值。或者,我们可以做一个参考点,然后读出值: int& a = ++ i;

However, in constrast, the expression returned by ++i is the location (lvalue) of i. Provoking an lvalue-to-rvalue conversion, like in int a = ++i; will read the value out of it. Alternatively, we can make a reference point to it, and read out the value later: int &a = ++i;.

也请注意生成右值的其他情况。例如,所有临时值都是右值,二进制/一元值+和负值以及不是引用的所有返回值表达式的结果。所有这些表达式不位于命名对象中,而只是携带相当的值。那些值当然可以由不恒定的对象备份。

Note also the other occasions where rvalues are generated. For example, all temporaries are rvalues, the result of binary/unary + and minus and all return value expressions that are not references. All those expressions are not located in an named object, but carry rather values only. Those values can of course be backed up by objects that are not constant.

下一个C ++版本将包括所谓的右值引用,即使它们指向nonconst,到右值。理由是能够从这些匿名对象窃取资源,并避免副本。假设一个类型重载了前缀++(返回 Object& )和后缀++(返回 Object ,以下将导致首先复制,对于第二种情况,它将从右值窃取资源:

The next C++ Version will include so-called rvalue references that, even though they point to nonconst, can bind to an rvalue. The rationale is to be able to "steal" away resources from those anonymous objects, and avoid copies doing that. Assuming a class-type that has overloaded prefix ++ (returning Object&) and postfix ++ (returning Object), the following would cause a copy first, and for the second case it will steal the resources from the rvalue:

Object o1(++a); // lvalue => can't steal. It will deep copy.
Object o2(a++); // rvalue => steal resources (like just swapping pointers)

这篇关于为什么++ i被认为是一个l值,但i ++不是?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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