Na przykład deklaracja taka jak:
int (x) = 0;
Albo nawet to:
int (((x))) = 0;
Natknąłem się na to, ponieważ zdarzyło mi się, że w swoim kodzie miałem fragment podobny do następującego:
struct B
{
};
struct C
{
C (B *) {}
void f () {};
};
int main()
{
B *y;
C (y);
}
Oczywiście chciałem skonstruować obiekt, C
który wtedy zrobiłby coś pożytecznego w swoim destruktorze. Jednak jak to bywa, kompilator traktuje C (y);
jako deklarację zmiennej y
o typie C
i dlatego wypisuje błąd dotyczący y
redefinicji. Ciekawe jest to, że jeśli napiszę to jako C (y).f ()
lub jako coś podobnego C (static_cast<B*> (y))
, skompiluje się zgodnie z przeznaczeniem. Najlepszym współczesnym obejściem jest {}
oczywiście użycie wywołania konstruktora.
Więc jak się później domyśliłem, możliwe jest zadeklarowanie zmiennych takich jak int (x) = 0;
lub nawet, int (((x))) = 0;
ale nigdy nie widziałem nikogo, kto faktycznie używa takich deklaracji. Więc jestem zainteresowany - jaki jest cel takiej możliwości, bo na razie widzę, że tworzy ona tylko przypadek podobny do osławionej "najbardziej irytującej analizy" i nie dodaje niczego pożytecznego?
źródło
Odpowiedzi:
Grupowanie.
Jako konkretny przykład rozważmy, że można zadeklarować zmienną typu funkcji, taką jak
int f(int);
Jak byś zadeklarował wskaźnik do takiej rzeczy?
int *f(int);
Nie, nie działa! Jest to interpretowane jako funkcja zwracająca
int*
. Musisz dodać w nawiasach, aby analizować we właściwy sposób:int (*f)(int);
To samo dotyczy tablic:
int *x[5]; // array of five int* int (*x)[5]; // pointer to array of five int
źródło
()
praca w typie jest jednolita w całym typie.Generalnie dopuszcza się używanie nawiasów w takich deklaracjach, ponieważ deklaracja, ze składniowego punktu widzenia, wygląda zawsze tak:
Na przykład w następującej deklaracji:
int* p[2];
„Typ frontu” to
int
(nieint*
), a „specyfikacja” to* p[2]
.Zasada jest taka, że w części dotyczącej specyfikacji można użyć dowolnej liczby nawiasów, ponieważ czasami nieuniknione jest ich ujednoznacznienie. Na przykład:
int* p[2]; // array of 2 pointers to int; same as int (*p[2]); int (*p)[2]; // pointer to an array of 2 ints
Wskaźnik do tablicy jest rzadkim przypadkiem, jednak ta sama sytuacja ma miejsce ze wskaźnikiem do funkcji:
int (*func(int)); // declares a function returning int* int (*func)(int); // declares a pointer to function returning int
To jest bezpośrednia odpowiedź na twoje pytanie. Jeśli twoje pytanie dotyczy tego stwierdzenia
C(y)
, to:(C(y))
a otrzymasz to, czego chciałeśźródło
{}
jest jednak najbardziej trafne.<front-type> <specification>
jest mylący i zły. Gramatyka to<declaration-specifier> <declarator>
<declaration-specifier>
może pełnićauto
słowo kluczowe, więc nie zawsze jest to typ.