C++多重继承场景下如何调用两层继承基类的隐藏方法
多重继承场景下限定名调用基类方法的合规性说明
示例代码如下:
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'
标准判定依据
根据C++标准的限定名查找规则,B::A 中的A是A类的注入类名:每个类都会将自身的类名注入到自身的作用域中,因此B::A最终解析得到的类型就是全局作用域下的::A,前缀B::仅用于查找A这个名称,并不会指定访问D类中B继承路径下的A子对象。
此时等价于直接对D类对象调用::A::f(),而D类同时从B、C两条非虚继承路径各继承了一个A类子对象,编译器无法确定要访问哪个A子对象的f方法,因此会报歧义错误。
合规的实现方式
如果需要明确调用B继承路径下A类的f方法,正确写法是先将D对象向上转型为B类型,再调用A类的f方法,该写法可在所有符合标准的编译器下正常运行:
int main() { static_cast<B&>(D{}).A::f(); }
编译器行为判定
- GCC、Clang的行为完全符合C++标准要求
- MSVC属于非标准的扩展实现,不符合标准规定
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

