C ++
我在互联网上阅读了很多,似乎很多人提到了以下规则(但我无法在标准中找到它),
加法运算符+(以及所有其他二元运算符)要求两个操作数都是右值,结果是右值。 等等..
我检查了C ++标准,并明确指出(第3.10 / 2条),
每当一个glvalue出现在预期prvalue的上下文中时,该glvalue将被转换为一个prvalue
(第5/9条),
每当一个glvalue表达式作为一个操作符的操作数出现,该操作数需要该操作数的一个值时,左值到右值(4.1),数组到指针(4.2)或函数到指针(4.3)的标准转换是用于将表达式转换为前值。
它使用一个术语操作数“预计”一个prvalue。 但是,当我查看加法运算符,乘法运算符等时,它只提到结果是一个prvalue,但它没有说什么操作数是“预期”的。
二元运算符是否真的期望这些操作数是值得尊重的,这在以下情况下会产生变化,
int b = 2;
int a = b + 1;
如果b预计是一个prvalue,那么在这里会有一个左值到右值的转换,然后它将执行prvalue + prvalue并返回一个prvalue,并将结果prvalue分配给一个左值a。
但是,如果b不需要是一个prvalue,它将是左值+预值,结果是一个值。
我真的很想知道标准在哪里明确或隐含地提到不同运营商的规则? 我检查了所有操作符部分,并且只检查了几个操作符,标准明确提到操作数和结果是左值还是右值。 对于大多数操作员来说,标准只提到结果,而不是操作数要求。
谢谢。
顺便说一句,我发现在标准5.19中关于常量表达式可能非常非常“隐含”意味着二元运算符要求在运算数上进行左值到右值的转换。 有关更多详细信息,请参阅我之前的问题,
混合使用constexpr和const?
一个条件表达式是一个常量表达式,除非它涉及以下之一作为潜在的评估子表达式(3.2)。
...
- 一个左值到右值的转换(4.1),除非它被应用于
----一个整数或枚举类型的glvalue,它引用一个具有前面初始化的非易失性const对象,用一个常量表达式初始化
谢谢阅读。
所以,这通常是标准中那些推断和不明确的部分之一; 然而,在3.10
[注意:有些内置运算符期望左值操作数。 [例如:内置的赋值操作符都希望左手操作数是左值。 - 结束示例]其他内置运算符产生rvalues,并且有些期望它们。 [例如:一元和二元运算符需要右值参数并产生右值结果。 - end example]对第5节中每个内置运算符的讨论指出它是否期望左值操作数以及它是否产生左值。 - 结束注释]
请注意,第5节中指定的语言很差“表示它是否期望左值操作数以及是否产生左值”。
第5章的检查表明,每一个表达式都需要或返回一个左值的情况被列举出来,但是很少有具体处理右值的情况被列举出来,我认为它假定其余部分被假定为右值。
我也怀疑这是没有明确规定的,因为从标准的角度来看,如果转换是由操作员隐式或明确完成的,则不是特别重要,不管该行为应该是一致和良好的行为。
(首先,对我的英语感到抱歉,更正绝对是好的)
该标准说:
§5.7-3二元+运算符的结果是操作数的总和。 [...]
假设我们有表达式e1 + e2
,并且所选的+
运算符是内置运算符,表达式格式良好, e1
和e2
是算术类型,或者转换为算术类型是可用的,并且一切正常,所以罚款和完美!
因此,规则§5.7-3适用。 另一方面,每个操作数都是一个表达式:
§5-1[注意:[...]表达式是指定计算的一系列运算符和操作数。 表达式可能会导致一个值,并可能导致副作用。 - 结束注释]
它说一个表达式可以导致一个值,因为void
表达式,比如delete
表达式或者一个void
函数,但是因为我们已经说过e1 + e2
是一个完美定义的表达式!所以我们可以省略动词“can”,所以我们可以证实: 表达式导致了一个值 。
最后一点:对于算术和逻辑内建运算符,我了解,尽管标准没有规定它,但只有它的操作数的值很重要,不管它们的值的类别如何。
我认为使用表达式足以实现内置的运算符+
(和其他算术运算符),因为只有值很重要,并且可以通过表达式达到该值。 出于这个原因,标准没有明确界定它们。
尽管如此,这种类型的结构非常糟糕。 例如,当运算符接收到一个作为操作数的对象而不是直接值(怀疑我目前正在尝试解决的问题)时,我发现没有地方指定,如果操作员应该直接取其值来计算操作符,如果该值是评估对象的结果,等等。 很明显,只有价值观才是重要的,但是,这些标准对于这些事情的确是一种神秘。
链接地址: http://www.djcxy.com/p/40289.html上一篇: c++