为什么后缀运算符++优先级高于前缀运算符++?
以这种方式定义,我们既不能做++x++
,也不能做++x--
。但另一方面, (++x)++
和 (++x)--
都是有用的表达式: (++x)++
将 x
加 2 并返回“中间”的值,而 (++x)--
本质上等同于 x+1
但完全避免了调用 operator+
,这有时非常有用。
那么为什么优先级没有定义为让 ++x++
自动扩展为 (++x)++
而不是 ++(x++)
?后者是否有一些我不明白的隐藏含义,或者只是为了将优先级保持为一个简单的列表,其中所有前缀运算符组成一个级别?
编辑 好吧,我没有明确地说,但是:当然我的意思是 x
是用户定义的类型。对于内置类型,(x+=2)-1
当然比 (++x)++
更好,而 x+1
> 比 (++x)--
好很多。我想到的情况是一个相当复杂类型的半关联容器的迭代器,其中运算符 +=
和 +
(为随机访问而设计)必须重建缓存以便有效地处理一般请求,因此比 ++
慢一个数量级。但当然我可以修改它们以始终首先检查参数是否是一个非常小的整数,在这种情况下只需重复调用 operator++
而不是执行随机访问过程。这在这里应该可以正常工作,尽管我可以想象我可能在某些时候遇到这样的情况:我希望operator+=始终采用随机访问方式,无论我提供的数字有多小。
So... for me, I would conclude the answer to be:
拥有一个简单且易于记忆的优先级列表(其中所有)后缀运算符都位于任何前缀运算符之前的优点足以容忍always的小缺点必须使用括号来组成前后运算符
++
/--
,因为这种组合很少使用。
更简单的“C 是这样做的”,虽然它看起来可能是真正的原因,但对我来说远不太令人满意,因为因为 ++x++
是不允许的完全在C中,可以在不损坏任何现有代码的情况下重新定义这个组合。
不管怎样,我会继续使用 (++x)--
,因为括号确实不会造成太大伤害。
Defined this way, we can do neither ++x++
nor ++x--
. But on the other hand, both (++x)++
and (++x)--
are useful expressions: (++x)++
increments x
by two and returns the value "in the middle", while (++x)--
is essentially equivalent to x+1
but completely avoids having to call operator+
, which can be quite useful sometimes.
So why is the precedence not defined to have ++x++
automatically expand to (++x)++
rather than ++(x++)
? Is there some hidden meaning to the latter which I don't understand, or is it just to keep the precedence a simple list with all prefix operators making up one single level?
EDIT Ok, I didn't explicitly say it, but: of course I meant x
to be user-defined type. For built-in types, (x+=2)-1
is of course better than (++x)++
, and x+1
is a lot better than (++x)--
. The situation that I have in mind is an iterator to a rather complicated type of semi-associative container, where operators +=
and +
(being designed for random access) have to rebuild a cache in order to work efficiently for general requests, and are therefore an order of magnitude slower than ++
. But of course I can modify them to always check first if the argument is a very small integer, and in that case just call operator++
repeatedly instead of doing the random-access procedure. That should work fine here, though I could imagine I might at some point have a situation in which I want operator+=
to always go the random-access way, regardless of how small numbers I present it.
So... for me, I would conclude the answer to be:
the advantage of having a simple and well-memorizeable precedence list in which all postfix operators come before any of the prefix operators is sufficient to tolerate the minor drawback of always having to use parentheses to compose pre- and postfix operators
++
/--
, as this composition is used very seldom.
The simpler "C does it this way", while it seems likely to be the real reason, is far less satisfying in to me, because since ++x++
was not allowed at all in C it would have been possible to redefine this very composition without damaging any existing code.
Anyway, I will go on using (++x)--
, as the parentheses really do not hurt so much.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为什么不
(x += 2) - 1
或(++x, x++)
?两者似乎都比较清楚。对于标量,两者在 C++03 中也都有明确定义,这与您建议的表达式相反。这是一个随意的说法,没有任何解释。所以我要把它扔进池子里:
只是为了使这种神秘的极端情况不会出错?决不。你能帮我背诵
man operator
吗?如果您做不到这一点,最好不要尝试在代码中编写++x++
。Why not
(x += 2) - 1
or(++x, x++)
? Both seem to be clearer. For scalars, both are well-defined also in C++03, as opposed to your proposed expression.That's an arbitrary statement without any explanation. So I'm going to throw into the pool:
Just to make such arcane corner cases not error out? No way. Can you please recite
man operator
for me? If you cannot do that, better not try and write++x++
in your code.C++ 标准只保留了 C 规则,显然考虑到运算符重载和尚未发明的语言中发明的惯用语,这些规则并未得到修复。
查看 DM Ritchie 主页 中提供的内容,发现此优先级已经存在存在于 B 中(一元运算符从右到左绑定。因此
-!x++
绑定于-(!(x++))
用户对 B) 和 I 的引用在 BCPL 中没有看到增量运算符。C++ standard just kept the C rules and obviously those weren't fixed considering operator overloading and idioms yet be invented in a yet to be invented language.
Looking at what is available in D.M. Ritchie Home Page, on see that this precedence is already present in B (Unary operators are bound right to left. Thus
-!x++
is bound-(!(x++))
in Users' Reference to B) and I didn't see increment operators in BCPL.(++x)++
和(++x)--
都调用 未定义的行为 [假设 x 是原始类型]。对于用户定义的类型,场景会有所不同。但是,通常不建议在代码中使用此类令人困惑的表达式。就优先级而言这个答案 解释了为什么后增量比预增量具有更高的优先级。
Both
(++x)++
and(++x)--
invoke undefined behaviour [assuming x to be a primitive type]. For user defined type the scenario would be different. However it is not generally recommended to use such confusing expressions in your code.As far as the precendence is concerned this answer explains why post increment has higher precedence than pre increment.