Почему C++ позволяет нам заключать имя переменной в круглые скобки при объявлении переменной?
например, такое объявление:
int (x) = 0;
или даже так:
int (((x))) = 0;
я наткнулся на это, потому что в моем коде у меня был фрагмент, похожий на следующий:
struct B
{
};
struct C
{
C (B *) {}
void f () {};
};
int main()
{
B *y;
C (y);
}
очевидно, я хотел построить объект C
что бы потом сделать что-то полезное в своем деструкторе. Однако как это бывает компилятор лечит C (y);
как объявление переменной y
С типом C
и таким образом он печатает ошибку о y
переопределение. Интересно то, что если я пишу это как C (y).f ()
или что-то вроде C (static_cast<B*> (y))
он будет компилироваться, как и предполагалось. Лучший современный обходной путь-использовать {}
в вызова конструктора, конечно.
так как я понял, после этого можно объявлять переменные типа int (x) = 0;
или даже int (((x))) = 0;
но я никогда не видел, чтобы кто-то через такое объявление. Поэтому мне интересно-какова цель такой возможности, потому что пока я вижу, что она только создает случай похож на пресловутый "самый досадный разбор" и не добавляет ничего полезного?
2 ответа:
группировки.
в качестве конкретного примера рассмотрим, что вы можете объявить переменную типа функции, например
int f(int);
теперь, как бы вы объявили указатель на такую вещь?
int *f(int);
нет, не работает! Это интерпретируется как функция, возвращающая
int*
. Вам нужно добавить в скобках, чтобы сделать его разобрать правильно:int (*f)(int);
то же самое с массивами:
int *x[5]; // array of five int* int (*x)[5]; // pointer to array of five int
в таких объявлениях обычно разрешается использовать круглые скобки, потому что объявление с синтаксической точки зрения всегда выглядит так:
<front type> <specification>;
например, в следующем объявлении:
int* p[2];
"передний тип" - это
int
(неint*
) и "спецификация" составляет* p[2]
.правило заключается в том, что вы можете использовать любое количество скобок по мере необходимости в части "спецификация", потому что они иногда неизбежны для распутать. Например:
int* p[2]; // array of 2 pointers to int; same as int (*p[2]); int (*p)[2]; // pointer to an array of 2 ints
указатель на массив является редким случаем, однако такая же ситуация у вас есть с указателем на функцию:
int (*func(int)); // declares a function returning int* int (*func)(int); // declares a pointer to function returning int
это прямой ответ на ваш вопрос. Если ваш вопрос о заявлении, как
C(y)
, тогда:
- поставить скобки вокруг всего выражения -
(C(y))
и вы получите то, что вы хотели- этот оператор не делает ничего, кроме создания временного объекта, который прекращает чтобы жить после окончания этой инструкции (я надеюсь, что это то, что вы намеревались сделать).