最令人烦恼的解析与合格身份 - 或不?

T.C*_*.C. 5 c++ most-vexing-parse

考虑:

struct Foo {
     enum { bar };
     explicit Foo(int){}
};

struct Baz { explicit Baz(Foo){} };

Baz b(Foo(Foo::bar)); // #1
Run Code Online (Sandbox Code Playgroud)

第1行是最令人烦恼的解析,即使它Foo::bar是一个限定ID并且不可能是一个有效的参数名称?Clang和GCC不同意 ; 哪个编译器是正确的?

T.C*_*.C. 8

Clang是对的.

有点令人惊讶的是,参数声明的语法允许使用qualifiednonqualified-id,因为它接受所有声明符:

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
Run Code Online (Sandbox Code Playgroud)

并且声明者的语法允许限定标准非限定标识."无资格-ID的功能参数名"的规则,是好还是坏,是一个语义规则,尽管可以容易地编写语法参数声明排除合格-ID小号直接.

就像这个问题中的情况一样,消歧规则纯粹是合成的,从那时起

Baz b(Foo(Foo::bar));
Run Code Online (Sandbox Code Playgroud)

可以合成地解析为函数声明,它被解析,即使在这种情况下消歧导致一些永远无法编译的东西.

另见clang bug 4594.