Por ejemplo, una declaración como esa:
int (x) = 0;
O incluso eso:
int (((x))) = 0;
Me encontré con esto porque en mi código tenía un fragmento similar al siguiente:
struct B
{
};
struct C
{
C (B *) {}
void f () {};
};
int main()
{
B *y;
C (y);
}
Obviamente, quería construir un objeto C
que luego haría algo útil en su destructor. Sin embargo, como sucede, el compilador la trata C (y);
como una declaración de variable y
con tipo C
y, por lo tanto, imprime un error sobre la y
redefinición. Lo interesante es que si lo escribo como C (y).f ()
o como algo parecido C (static_cast<B*> (y))
, se compilará según lo previsto. La mejor solución alternativa moderna es utilizar{}
en la llamada al constructor, por supuesto.
Entonces, como descubrí después de eso, es posible declarar variables como int (x) = 0;
o incluso, int (((x))) = 0;
pero nunca he visto a nadie usar declaraciones como esta. Así que estoy interesado, ¿cuál es el propósito de tal posibilidad porque por ahora veo que solo crea el caso similar al notorio "análisis más irritante" y no agrega nada útil?
fuente
Respuestas:
Agrupamiento.
Como ejemplo particular, considere que puede declarar una variable de tipo de función como
int f(int);
Ahora, ¿cómo declararías un puntero a algo así?
int *f(int);
¡No, no funciona! Esto se interpreta como una función que regresa
int*
. Debe agregar los paréntesis para que se analice de la manera correcta:int (*f)(int);
El mismo trato con las matrices:
int *x[5]; // array of five int* int (*x)[5]; // pointer to array of five int
fuente
()
funciona un tipo es uniforme en todo el tipo.Por lo general, se permite el uso de paréntesis en tales declaraciones porque la declaración, desde el punto de vista sintáctico, siempre se ve así:
Por ejemplo, en la siguiente declaración:
int* p[2];
El "tipo frontal" es
int
(noint*
) y la "especificación" es* p[2]
.La regla es que puede usar cualquier número de paréntesis según sea necesario en la parte de "especificación" porque a veces es inevitable eliminar la ambigüedad. Por ejemplo:
int* p[2]; // array of 2 pointers to int; same as int (*p[2]); int (*p)[2]; // pointer to an array of 2 ints
El puntero a una matriz es un caso raro, sin embargo, la misma situación que tiene con un puntero para funcionar:
int (*func(int)); // declares a function returning int* int (*func)(int); // declares a pointer to function returning int
Esta es la respuesta directa a tu pregunta. Si su pregunta es sobre la declaración como
C(y)
, entonces:(C(y))
y obtendrá lo que queríafuente
{}
es la más válida después de todo.<front-type> <specification>
es engañoso y erróneo. La gramática es<declaration-specifier> <declarator>
<declaration-specifier>
también se puede jugar porauto
palabra clave, por lo que ni siquiera siempre es un tipo.