Trato de comprender los tipos de expresión de C ++ y cuanto más leo, más confundido estaba, ya que encuentro que el borrador de C ++ es muy difícil de digerir y, por lo tanto, prefiero otros recursos, pero se contradicen entre sí o no tienen en cuenta que la redacción y la definición entre versiones de C ++ cambian mucho.
A continuación me refiero a los siguientes borradores:
- C ++ 11 [ n3690 ] (borrador final)
- C ++ 17 [ n4659 ] (borrador final)
- C ++ 20 [ n4835 ] (borrador actual)
C++11
3.10 Valores y valores... Un valor prva (valor "puro") es un valor r que no es un valor x. [Ejemplo: el resultado de llamar a una función cuyo tipo de retorno no es una referencia es un prvalue. El valor de un literal como 12, 7.3e5 o verdadero también es un prvalue. - ejemplo final]
C++17
3.10 Valores y valores... Un prvalue es una expresión cuya evaluación inicializa un objeto o un campo de bits, o calcula el valor del operando de un operador, según lo especificado por el contexto en el que aparece.
C++20
7.2.1 Categorías de valor *... Un prvalue es una expresión cuya evaluación inicializa un objeto o un campo de bits, o calcula el valor de un operando de un operador, según lo especificado por el contexto en el que aparece, o una expresión que tiene el tipo cv void.
Entendería los cambios de redacción, y se hacen algunos ajustes, pero para mí la definición completa cambia. ¿Alguien puede ayudarme a entender esto? Por ejemplo, ¿por qué se eliminó la oración de que un prvalue es un rvalue que no es un xvalue? ¿O por qué se eliminó el útil ejemplo?
Respuestas:
La definición original de prvalue era solo una etiqueta: dejamos de lado ciertos valores (es decir, aquellos que no son valores x) y les damos un nombre. Es imposible tomar su dirección, excepto a través de un
this
uso inusual (más o menos porque son temporales), por lo que se pueden tomar ciertas libertades con su creación y propagación sin romper nada. (Véase también una discusión reciente sobre ellos que no "tienen identidad").La nueva definición dice explícitamente que un prvalue es una inicialización "esperando que suceda": una vez que se identifica un objeto de destino, es lo que se inicializa. (Es importante tener en cuenta que la inicialización todavía ocurre cuando se construye el prvalue, pero no donde está). Esto se conoce con el nombre de "elisión de copia obligatoria" basada en la optimización equivalente que ya era común.
En cuanto al ejemplo, las nuevas definiciones de categoría de valor se consideraron mucho más simples y se necesitaron menos ejemplos. Todavía hay uno para los valores x (que son la categoría más sutil).
fuente