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