【问题标题】:Regarding lvalue-to-rvalue conversion, when is it required?关于左值到右值的转换,什么时候需要?
【发布时间】:2011-07-03 06:07:10
【问题描述】:

我在网上看了很多,似乎很多人提到了以下规则(但我在标准中找不到),

加法运算符 +(和所有其他二元运算符)要求两个操作数都是右值,结果是右值。 等等……

我检查了 C++ 标准,它明确指出(第 3.10/2 条),

每当一个左值出现在 期望prvalue的上下文, 泛左值被转换为纯右值

(第 5/9 条),

每当出现左值表达式时 作为运算符的操作数 期望该操作数的纯右值, 左值到右值(4.1), 数组到指针(4.2),或 函数到指针 (4.3) 标准 转换应用于转换 prvalue 的表达式。

它使用操作数“期望”一个纯右值的术语。然而,当我研究加法运算符、乘法运算符等时,它只提到,结果是一个纯右值,但它没有说明操作数“预期”是什么。

二元运算符是否真的期望操作数是纯右值在以下情况下会有所不同,

int b = 2;
int a = b + 1;

如果b期望是prvalue,这里会有一个lvalue-to-rvalue的转换,然后执行prvalue + prvalue,返回一个prvalue,结果prvalue赋值给一个lvalue a。

但是,如果 b 不需要是纯右值,则它将是左值 + 纯右值,结果是纯右值。

我真的很想知道标准在哪里明确或暗示提到 不同运营商的规则?我检查了所有操作符部分,并且只有少数标准明确提到操作数和结果应该是左值还是右值。对于大多数运算符来说,标准只提到了结果,而没有提到操作数要求。

谢谢。


顺便说一句,我在标准 5.19 中发现关于常量表达式的内容可能非常非常“隐含”地暗示二元运算符需要对操作数进行左值到右值的转换。更多详情请参考我之前的问题,

mixing use of constexpr and const?

条件表达式是一个常数 表达,除非它涉及其中之一 以下作为潜在的 评估子表达式 (3.2)。

...

——左值到右值的转换 (4.1) 除非它适用于

———— 一个glvalue 整数或枚举类型 指的是一个非易失的 const 对象 使用前面的初始化, 用常量表达式初始化

感谢阅读。

【问题讨论】:

    标签: c++ rvalue lvalue lvalue-to-rvalue


    【解决方案1】:

    (首先,对不起我的英语。绝对欢迎更正)

    标准说:

    §5.7-3 二元 + 运算符的结果是操作数的和。 [...]

    假设我们有表达式e1 + e2,并且选择的+ 运算符是内置运算符,表达式格式正确,e1e2 是算术类型或转换为算术类型是可用的,一切都很好,很好,很完美!

    因此,适用规则 §5.7-3。另一方面,每个操作数都是一个表达式:

    §5-1 [注意:[...] 表达式是指定计算的运算符和操作数序列。表达式可能会产生一个值并可能导致副作用。 — 尾注]

    它说一个表达式可以因为void表达式产生一个值,比如delete表达式或void函数,但既然我们已经说过e1 + e2是一个完美的-定义表达式!,我们可以省略动词“can”,因此我们可以确认:表达式产生值

    最后一点:对于算术和逻辑内置运算符,我理解,虽然标准没有规定,但只有其操作数的值很重要,与它们的值类别无关。

    我认为作为表达式足以实现内置运算符+(和其他算术运算符),因为只有值很重要,并且可以通过表达式达到值。出于这个原因,标准没有明确定义它们。

    同样,这类事情的结构非常糟糕。例如,我发现没有指定位置,当运算符接收对象作为操作数而不是直接值时(怀疑我目前正在尝试解决),如果运算符应该直接取其值来计算运算符,如果该值是评估对象的结果,依此类推。很明显,只有价值观很重要,但是,这些东西的标准到底是什么却是一个谜。

    【讨论】:

      【解决方案2】:

      因此,这通常是标准中那些推断和指定不明确的部分之一;但是,在 3.10

      [ 注意:一些内置运算符需要左值操作数。 [ 示例:内置赋值运算符都希望它们的左操作数是左值。 — 结束示例] 其他内置运算符产生右值,有些人期望它们。 [ 示例:一元和二元 + 运算符期望右值参数并产生右值结果。 — 结束示例] 第 5 节中对每个内置运算符的讨论表明它是否需要左值操作数以及它是否产生左值。 ——尾注]

      请注意“第 5 条中指定的语言不明确指出它是否需要左值操作数以及是否产生左值”。

      对第 5 章的检查表明,表达式需要或返回左值的每种情况都被枚举了,但是很少有专门处理右值的情况被枚举,我认为然后假设其余的被假定为右值。

      我还怀疑它没有指定好,因为从标准的角度来看,转换是否由操作员隐式或显式完成并不是特别重要,无论如何,行为应该是一致且行为良好的。

      【讨论】:

      • 谢谢。但是,您引用的上述陈述在新标准N3225中被删除了......难怪我找不到它..我认为这是不同人处理不同部分的问题,并没有考虑太多一致性问题.
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-24
      • 1970-01-01
      • 2013-07-12
      • 1970-01-01
      • 2014-01-17
      • 1970-01-01
      • 2020-09-19
      相关资源
      最近更新 更多