考虑一个结构体
B
,它派生自两个结构体A<1>
和A<2>
,每个结构体定义了一个名为D
的类型,并且还有一个全局的名为D
的类型。然后在B
对象后面写入.D::
,应该选哪个D
?template<int N> struct A{ int v = N; using D = A; };
struct B : A<1>, A<2> {};
using D = A<1>;
int main() { return B{}.D::v; }
根据标准:[basic.lookup.classref]
4 If the id-expression in a class member access is a qualified-id of the form
class-name-or-namespace-name::...
the
class-name-or-namespace-name
following the.
or->
operator is first looked up in the class of the object expression ([class.member.lookup]) and the name, if found, is used. Otherwise it is looked up in the context of the entire postfix-expression.
首先,必须查找结构体B
中的D
,但在那里它是模糊的。事实上,Clang报告了一个错误:
error: member 'D' found in multiple base classes of different types
但是GCC接受了这段代码,示例:https://gcc.godbolt.org/z/74qraoeac
看起来,GCC将标准解释为在B
中D
是有歧义的,让我们看看B
之外。哪个编译器在这里是正确的?
return B{}.::D::v;
,两者都会很满意。我倾向于在原始代码中(在查找有歧义的“D”所在的封闭命名空间之前),使用clang++
正确地查找“B”中的“D”。 - Ted Lyngmo