考虑:
struct Foo {
enum { bar };
explicit Foo(int){}
};
struct Baz { explicit Baz(Foo){} };
Baz b(Foo(Foo::bar)); // #1
第 1 行是否是最令人头疼的解析,即使它Foo::bar
是一个限定 ID并且不可能是一个有效的参数名称?Clang 和 GCC 不同意;哪个编译器是正确的?
考虑:
struct Foo {
enum { bar };
explicit Foo(int){}
};
struct Baz { explicit Baz(Foo){} };
Baz b(Foo(Foo::bar)); // #1
第 1 行是否是最令人头疼的解析,即使它Foo::bar
是一个限定 ID并且不可能是一个有效的参数名称?Clang 和 GCC 不同意;哪个编译器是正确的?
叮当是对的。
有点令人惊讶的是,参数声明的语法同时允许qualified-和unqualified-id,因为它接受所有的declarator:
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
并且声明符的语法允许qualified-和unqualified-id。“函数参数名称没有限定 id ”规则,无论好坏,都是语义规则,尽管可以很容易地为参数声明编写一个语法,直接排除qualified-id。
就像这个问题的情况一样,消歧规则是纯句法的,因为
Baz b(Foo(Foo::bar));
可以在语法上被解析为函数声明,它是如此解析,即使在这种情况下的消歧导致一些永远无法编译的东西。
另请参阅clang 错误 4594。