一元*运算符的操作数是否需要纯右值

Does the operand of unary* operator expect a prvalue

int main(){
  int a = 0;
  auto ptr = &a;
  auto&& rf = *ptr;
}

考虑上面的代码,当泛左值ptr被用作一元*运算符的操作数时,是否需要对其应用左值到右值的转换?即,一元*运算符的操作数是否需要纯右值?

问题 1:

expr.unary.op#1

The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points. If the type of the expression is “pointer to T”, the type of the result is “T”. [ Note: Indirection through a pointer to an incomplete type (other than cv void) is valid. The lvalue thus obtained can be used in limited ways (to initialize a reference, for example); this lvalue must not be converted to a prvalue, see [conv.lval].  — end note ]

一元*运算符的操作数期望什么样的值类别。


除了这个运算符,[expr]中的大多数运算符似乎都没有指定其操作数期望什么样的值类别。

expr#9

Whenever a glvalue expression appears as an operand of an operator that expects a prvalue for that operand, the lvalue-to-rvalue, array-to-pointer, or function-to-pointer standard conversions are applied to convert the expression to a prvalue. [ Note: Because cv-qualifiers are removed from the type of an expression of non-class type when the expression is converted to a prvalue, an lvalue expression of type const int can, for example, be used where a prvalue expression of type int is required.  — end note ].

上面的引述很不清楚。

问题 2:

如前所述,[expr]中的大多数运算符都没有指定其操作数期望什么样的值类别。所以它是一个缺陷?

一般来说就是CWG1642:

1642. Missing requirements for prvalue operands

Although the note in 6.10 [basic.lval] paragraph 1 states that

The discussion of each built-in operator in Clause 8 [expr] indicates the category of the value it yields and the value categories of the operands it expects

事实上,许多采用纯右值操作数的运算符并没有明确要求。解决此失败的可能方法是笼统声明,即假定未指定值类别的操作数为纯右值;将 prvalue 要求添加到每个缺少它的操作数描述中;或更改通常的算术转换的描述,以声明它们暗示左值到右值的转换,这将涵盖大部分遗漏。

特别是 [expr.unary.op]/1 的措辞应该由 this PR 修正。