¿Cuál es la categoría de valor de los operandos de los operadores de C ++ cuando no se especifica?

PREMISA:

El estándar C ++ 11 clasifica las expresiones en tres categorías de valores disjuntas: lvalues , xvalues y prvalues (§ 3.10 / 1). Una explicación de qué categorías de valores está disponible, por ejemplo, aquí .

Estoy luchando para averiguar cuáles son los requisitos de los diferentes operadores en la categoría de valor de sus operandos. El párrafo 3.10 / 1 especifica:

[…] Cada expresión pertenece exactamente a una de las clasificaciones fundamentales de esta taxonomía: lvalue, xvalue o prvalue. Esta propiedad de una expresión se llama su categoría de valor. [Nota: la discusión de cada operador incorporado en la Cláusula 5 indica la categoría del valor que produce y las categorías de valores de los operandos que espera . Por ejemplo, los operadores de asignación integrados esperan que el operando de la izquierda sea un valor l y que el operando de la derecha sea un valor de pr y arroje un valor de l como resultado . Los operadores definidos por el usuario son funciones, y las categorías de valores que esperan y generan están determinadas por sus parámetros y tipos de retorno. -Finalizar nota]

A pesar de lo que afirma la nota anterior, la Cláusula 5 no siempre es muy clara sobre la categoría de valor de los operandos de los operadores. Esto es, por ejemplo, todo lo que se dice sobre la categoría de valor de los operandos del operador de asignación (Párrafo 5.17 / 1):

El operador de asignación (=) y los operadores de asignación compuesta todos agrupan de derecha a izquierda. Todos requieren un valor l modificable como su operando izquierdo y devuelve un valor l referente al operando de la izquierda . El resultado en todos los casos es un campo de bits si el operando izquierdo es un campo de bits. En todos los casos, la asignación se secuencia después del cálculo del valor de los operandos derecho e izquierdo, y antes del cálculo del valor de la expresión de asignación. Con respecto a una llamada de función con secuencia indeterminada, la operación de una asignación compuesta es una única evaluación. [Nota: Por lo tanto, una llamada a función no debe intervenir entre la conversión lvalor a rvalue y el efecto secundario asociado con cualquier operador de asignación compuesta único. -Finalizar nota]

¿Qué tal los operandos correctos?

Las palabras “rvalue” y “lvalue” ya no aparecen en toda la Sección 5.17. Si bien la nota del párrafo 3.10 / 1 hace explícito que los operadores de asignación integrados esperan un valor pr como un operando de la derecha, esto no se menciona explícitamente en la Sección 5.17. Incluso la nota final de 5.17 / 1, que menciona las conversiones de valor a validación, parece implicar que de algún modo se esperan valores r (¿qué necesidad hay de una conversión?), Pero las notas no son normativas después de todo.

Las secciones relativas a otros operadores, incluidos los operadores multiplicativos y aditivos, generalmente no dicen nada sobre la categoría de valor de sus operandos. No pude encontrar ninguna “statement predeterminada” en la Norma que establezca que, cuando no se especifica lo contrario, los operandos de los operadores incorporados son valores r. Por lo tanto, la pregunta.

PREGUNTA:

  1. Cuál es la categoría de valor del operando correcto del operador de asignación ; y, de manera más general
  2. ¿Cómo averiguar la categoría de valor del operando de un operador cuando no se especifica ? ¿No está restringido (lo que significa que se acepta cualquier categoría de valor)? En caso afirmativo, ¿por qué las conversiones lvalue-to-rvalue deben aplicarse en una expresión de asignación?

Las referencias al estándar C ++ 11 son muy apreciadas.

Sí, está mal especificado y se ha cubierto antes . Básicamente, cada vez que se requiere una expresión lvalue se enumera, por lo que suponemos que cada otro operando debe ser una expresión prvalue.

Entonces para responder a sus preguntas:

  1. Un prvalue
  2. Si no está especificado, es un valor prve.

La nota que se cita en la respuesta vinculada parece haber cambiado algunas veces. La cita de §3.10 del estándar C ++ 11 es la siguiente (y en el momento actual es idéntica en el último borrador):

[Nota: la discusión de cada operador incorporado en la Cláusula 5 indica la categoría del valor que produce y las categorías de valores de los operandos que espera. Por ejemplo, los operadores de asignación integrados esperan que el operando de la izquierda sea un valor l y que el operando de la derecha sea un valor de pr y arroje un valor de l como resultado. Los operadores definidos por el usuario son funciones, y las categorías de valores que esperan y generan están determinadas por sus parámetros y tipos de retorno. – nota final]

Aquí incluso dice explícitamente que los operadores de asignación esperan que el operando correcto sea un valor prve. Por supuesto, esta es una nota y, por lo tanto, no es normativa.