Самый неприятный разбор с квалифицированным идентификатором - или нет?
Рассматривать:
struct Foo {
enum { bar };
explicit Foo(int){}
};
struct Baz { explicit Baz(Foo){} };
Baz b(Foo(Foo::bar)); // #1
Строка № 1 - самый неприятный анализ, хотя Foo::bar
является квалифицированным идентификатором и не может быть допустимым именем параметра? Clang и GCC не согласны; какой компилятор правильный?
1 ответ
Clang прав.
Несколько удивительно, что грамматика для объявления параметров допускает как квалифицированные, так и неквалифицированные идентификаторы, потому что она принимает все объявления:
parameter-declaration:
attribute-specifier-seq_opt decl-specifier-seq declarator
attribute-specifier-seq_opt decl-specifier-seq declarator = initializer-clause
attribute-specifier-seq_opt decl-specifier-seq abstract-declarator_opt
attribute-specifier-seq_opt decl-specifier-seq abstract-declarator_opt = initializer-clause
а грамматика для декларатора допускает как квалифицированные, так и неквалифицированные идентификаторы. Правило "нет квалифицированного идентификатора для имен параметров функции", к лучшему или худшему, является семантическим правилом, даже если легко написать грамматику для объявления параметров, которая напрямую исключает квалифицированные идентификаторы.
Как и ситуация в этом вопросе, правило устранения неоднозначности является чисто синтетическим, и поскольку
Baz b(Foo(Foo::bar));
может быть синтаксически проанализирован как объявление функции, поэтому он анализируется, даже если устранение неоднозначности в этом случае приводит к тому, что никогда не скомпилируется.
Смотрите также лягушка ошибка 4594.