如何从 C++ 中的两次继承基 class 调用隐藏方法?

How to call a hidden method from two times inherited base class in C++?

考虑一个 class D 继承自两个 classes BC,每个继承非虚拟 class A。在 A 中有一个方法 f,在 B 中有一个相同的命名方法隐藏了 A 中的方法。我想从 D 对象的 B-base class 调用 A::f(),如下所示:

struct A { void f() {} };
struct B : A { void f() {} };
struct C : A {};
struct D : B, C {};
int main() { D{}.B::A::f(); }

不幸的是,它只适用于 MSVC,而 GCC 和 Clang 都会产生错误:

error: 'A' is an ambiguous base of 'D'

演示:https://gcc.godbolt.org/z/jY3v876hK

看起来 GCC/Clang 接受但完全忽略 B::A::f() 中的 B:: 前缀。他们按照标准这样做对吗?

Are they right in doing so according to the standard?

是的。 A::B::AD::B::A 中的嵌套名称说明符都用于相同的目的,将 class 命名为 A.

[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.

嵌套名称说明符没有命名成员的“路径”,它命名了 D 的基础。并且命名 A 导致歧义。

其他答案说明编译器正确的原因。

为了达到你想要的效果,你可以这样做:

int main() { static_cast<B&&>(D{}).A::f(); }

虽然有点丑。

https://gcc.godbolt.org/z/Mzs8rsdf5