c++ c++11 c++14 decltype type-deduction

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:

  1. Mississippi tiene 2,320 millas de largo.
  2. 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.