auto c++
¿Cuál es la razón detrás del comportamiento de tipo decltype? (3)
De uno de los autores de la propuesta de
decltype
, J. Jarvi:
Ha pasado un tiempo, pero esto es lo que (creo que recuerdo):
Nunca se consideraron dos palabras clave separadas para diferenciar estos dos tipos de semántica. (Introducir nuevas palabras clave no se hace a la ligera).
En cuanto al cambio de la semántica del
decltype((x))
, la discusión en el grupo de trabajo central convergió a tratar(x)
como una expresión, en lugar de un identificador, que quizás sea más "internamente consistente" con las reglas del lenguaje.La gente sabía que esto podría ser confuso en algunos casos, pero el consenso (aunque quizás no sea la preferencia de todos) eventualmente sería consistente con la definición previa estándar de qué es un identificador y qué es una expresión.
El ejemplo al que se vincula [el ejemplo de esta pregunta] es realmente sorprendente. En ese momento, deducir el tipo de retorno de una función de su expresión de retorno usando
decltype(auto)
todavía no era parte del lenguaje, por lo que no creo que este caso de uso en particular estuviera en el radar de nadie.
Como entendí en C ++ 11,
decltype(expression)
se usa para deducir exactamente el mismo tipo de la expresión dada.
Pero cuando la expresión se pone entre paréntesis, el tipo de
deducciones
es una
referencia de valor
al tipo de expresión.
Por ejemplo:
int x;
decltype(x) y = x;
es equivalente a
int y = x;
pero,
int x;
decltype((x)) y = x;
es equivalente a
int& y = x;
.
Respectivamente
decltype(auto) f1()
{
int x = 0;
return x; // decltype(x) is int, so f1 returns int
}
pero
decltype(auto) f2()
{
int x = 0;
return (x); // decltype((x)) is int&, so f2 returns int&
}
¿Cuál es el fundamento para que este comportamiento sea elegido por el comité estándar?
Despues de las palabras:
Ahora observé que al menos en el caso de la implementación de
GCC 6.2
cuando la expresión entre paréntesis es más compleja, por ejemplo
decltype((x + x))
el tipo deducido es
T
, pero no
T&
.
Esto es aún más confuso.
No sé si este comportamiento es estándar.
Hay alguna necesidad de discriminar entre una entidad y una expresión.
Considere la siguiente pregunta:
¿Cuánto dura Mississippi?
Hay dos respuestas a esta pregunta:
- Mississippi tiene 2,320 millas de largo.
- Mississippi tiene 11 letras de largo.
De manera similar, cuando pregunta sobre el tipo de
x
,
x
es un identificador, no está claro si se refiere al tipo que se utilizó para declarar ese identificador (es decir, el tipo asociado con el nombre
x
), o el tipo de expresión que consiste de la única mención de ese identificador.
De hecho, podría haber dos palabras clave diferentes (por ejemplo,
entity_type
y
expr_type
) en lugar de un solo
decltype
sobrecargado.
Por alguna razón, el comité eligió sobrecargar
decltype
para esos dos usos diferentes.
Querían una forma de obtener el tipo de declaración de un identificador.
También querían una forma de obtener el tipo de expresión, incluida información sobre si es temporal o no.
decltype(x)
da el tipo declarado del identificador
x
.
Si pasa
decltype
algo que no es un identificador, determina el tipo, luego agrega
&
para lvalues,
&&
para xvalues, y nada para prvalues.
Conceptualmente, puede pensarlo como la diferencia entre el tipo de una variable y el tipo de una expresión. Pero no es así como lo describe el estándar.
Podrían haber usado dos palabras clave diferentes para significar estas dos cosas. Ellos no.