2010-06-22 17 views
42

No entiendo la última línea del ejemplo de la página 148 de la FCD (§7.6.1.2/4):decltype y paréntesis

const int&& foo(); 
int i; 
struct A { double x; }; 
const A* a = new A(); 
decltype(foo()) x1 = i;  // type is const int&& 
decltype(i) x2;    // type is int 
decltype(a->x) x3;   // type is double 
decltype((a->x)) x4 = x3; // type is const double& 

¿Por qué los paréntesis hacen una diferencia en este caso? ¿No debería simplemente ser double como en la línea de arriba?

Respuesta

35

Justo por encima de ese ejemplo, se dice

  • si e es un id-expresión unparenthesized o un miembro de la clase de acceso (5.2.5), decltype (e) es el tipo de la entidad nombrada por mi.
  • si e es un lvalue, decltype (e) es T &, donde T es el tipo de e;

creo decltype(a->x) es un ejemplo del "acceso de los miembros de clase" y decltype((a->x)) es un ejemplo de valor izquierdo.

+0

Pero eso no explica la const :) – fredoverflow

+5

@FredOverflow: ¿También: 'a' tiene tipo' const A * ' – Cubbi

+1

¿Cómo no he visto la const ??? Gracias :) – fredoverflow

8

Los paréntesis agregados lo están convirtiendo en un lvalor.

MSDN says
Los paréntesis internos hacen que la declaración se evalúe como una expresión en lugar de un acceso de miembro. Y como a se declara como un puntero const, el tipo es una referencia a const double.

16
decltype(a->x) 

Esto le da el tipo de la variable miembro A::x, que es double.

decltype((a->x)) 

Esto le da el tipo de la expresión (a->x), que es una expresión valor-I (de ahí por qué es una constante reference-- a es una const A*).

+4

Bien, entiendo cómo las reglas se pueden aplicar aquí ahora, pero * ¿por qué * son las reglas como esa? ¿Por qué tiene sentido distinguir entre 'a-> x' y' (a-> x) '? Me parece tan aleatorio. ¿Por qué querría ese comportamiento? ¿Algunas ideas? – fredoverflow

+0

Gracias, pero ambos 'decltype (f())' y 'decltype ((f()))' dan 'int' en mi sistema. ¿Te entendí mal? – fredoverflow

+0

@Fred: No importa. Estaba equivocado. En ese caso particular, los paréntesis se ignoran, por lo que ambos deben ser 'const int'. –