未指定时,C ++运算符的操作数的值类别是什么?

时间:2013-02-20 22:33:27

标签: c++ c++11 operators language-lawyer rvalue

的前提:

C ++ 11 Standard将表达式分为三个不相交的值类别 lvalues xvalues prvalues (§3.10/ 1)。例如here可以获得对值类别的解释。

我正在努力弄清楚不同运营商对其操作数的值类别的要求是什么。第3.10 / 1段规定:

  

[...]每个表达式都属于此分类法中的基本分类之一:lvalue,xvalue或prvalue。表达式的此属性称为其值类别。 [注意:第5条中对每个内置运算符的讨论表明它产生的值的类别以及它所期望的操作数的值类别。例如,内置赋值运算符期望左操作数是左值,右操作数是prvalue并产生左值作为结果。用户定义的运算符是函数,它们期望和产生的值的类别由它们的参数和返回类型决定。 - 后注]

尽管上面的说明声称,但第5条并不总是非常明确运营商的操作数的价值范畴。例如,这是关于赋值运算符的操作数的值类别的所有内容(第5.17 / 1段):

  

赋值运算符(=)和复合赋值运算符从右到左分组。 全部需要一个可修改的左值作为左操作数,并返回一个左值操作数的左值。如果左操作数是位字段,则所有情况下的结果都是位字段。在所有情况下,在右和左操作数的值计算之后,以及在赋值表达式的值计算之前,对赋值进行排序。对于不确定序列的函数调用,复合赋值的操作是单个评估。 [注意:因此,函数调用不应介入左值到右值转换和与任何单个复合赋值运算符相关的副作用。 - 后注]

正确的操作数怎么样?

整个5.17节中不再出现“rvalue”和“lvalue”字样。虽然第3.10 / 1段中的注释明确指出内置赋值运算符期望将prvalue作为右操作数,但在第5.17节中没有明确提到。甚至5.17 / 1的最后一个注释,提到左值到右值的转换,似乎暗示rvalues是以某种方式预期的(否则转换的需要是什么?),但是注释毕竟是非规范性的。

关于其他运算符的部分,包括乘法运算符和加法运算符,通常对其操作数的值类别保持沉默。我在标准中找不到任何“默认语句”,声明如果没有另外指定,内置运算符的操作数是rvalues。因此,问题。

问题:

  1. 赋值运算符的右操作数的值类别是什么;而且,更一般地说
  2. 如果未指定运算符的操作数的值类别,如何确定?它是不受约束的(意味着接受任何价值类别)?如果是这样,为什么Lvalue-to-rvalue转换应用于赋值表达式?
  3. 非常感谢对C ++ 11标准的引用。

1 个答案:

答案 0 :(得分:7)

是的,这是不明确的has been covered before。基本上,每次枚举表达式都是枚举的,所以我们假设每个其他操作数必须是一个prvalue表达式。

所以回答你的问题:

  1. prvalue。
  2. 如果未指定,则为prvalue。
  3. 链接答案中引用的注释似乎已经改变了几次。 C ++ 11标准§3.10的引用如下(目前在最新草案中是相同的):

      

    [注意:第5章中对每个内置运算符的讨论表明了它产生的值的类别以及它所期望的操作数的值类别。例如,内置赋值运算符期望左操作数是左值,右操作数是prvalue并产生左值作为结果。用户定义的运算符是函数,它们期望和产生的值的类别由它们的参数和返回类型决定。 - 结束说明]

    这里甚至明确指出赋值运算符期望右操作数是prvalue。当然,这是一个注释,因此是非规范性的。