Подтвердить что ты не робот

Почему это незаконно, чтобы определить указатель на переменную-указатель с нотацией вызова конструктора?

Когда я использую нотацию конструктора (declare-), определяющую указатель на указатель (вместо нотации назначения - конечно, что будет делать то же самое во время выполнения, это просто соглашение), я получаю ошибку компилятора. Мне было интересно, почему это так.

struct  Foo 
{ /* ... */ };

int main(int argc, char** argv)
{
  Foo*  parFoo = new Foo[2];
  Foo** ppFoo(&parFoo); // invalid: C2059
  Foo** ppFoo = &parFoo; // OK

  delete[] parFoo;
}

Ошибка - это недействительный токен C2059, который не говорит много. Однако & не является проблемой (это означает, что это, вероятно, не ошибка приоритета оператора). Если я сделаю следующее:

int main(int argc, char** argv)
{
  Foo*  parFoo = new Foo[2];
  Foo** ppFoo = &parFoo; // OK
  Foo** ppFoo2(ppFoo); // invalid: C2061

  delete[] parFoo;
}

... тогда я получаю C2061, что означает, что на этот раз это идентификатор ppFoo, который находится в неправильном месте.

Какое синтаксическое правило вызывает это, т.е. почему нельзя использовать обозначение вызова конструктора для определения указателей на указатели, только "меньше указаний на типы"?

4b9b3361

Ответ 1

Он выглядит как действительный С++. И, как указывали другие, GCC его принимает. В соответствии с ошибкой компилятора, это выглядит как ошибка в парсере MSVC.

Фактически добавление скобок помогает правильно разобрать код:

Foo*  parFoo = new Foo[2];
Foo (**ppFoo2)(&parFoo); // compiles in MSVC too

Ответ 2

В VS2005 код можно свести к простому

int main() {
  int** ppFoo(0);
}

и генерирует ту же ошибку. Очевидно, что это ошибка в компиляторе.