C++中能否使用子类类名限定的方法调用父类实例?
问题背景
我们先看对应的代码场景:
存在包含方法f的结构体A,以及继承自A、未重写f的结构体B,此时B::f最终指向的就是A中定义的f方法。
现在尝试用如下方式调用:
struct A { void f() {} }; struct B : A {}; int main() { A{}.B::f(); }
上述代码在不同编译器下表现完全不同:Clang可正常编译,GCC则直接抛出编译错误:
error: 'B' is not a base of 'A'
标准结论
GCC的处理完全符合C++标准规定,Clang的可编译表现属于编译器实现缺陷。
规则依据
根据C++标准[expr.ref]章节的明确要求:
对于类成员访问表达式
E1.E2,如果E2是带嵌套前缀的限定名(形如N::xxx),则N必须是E1的静态类型本身,或者是E1静态类型的直接/间接基类。
放到当前示例中:成员访问的左侧对象A{}的静态类型是A,而右侧方法名的嵌套前缀是B,B是A的派生类而非基类,完全不满足标准要求的前提,因此代码本身是非法的,GCC的报错符合标准规定。
补充说明:即便B::f最终解析到的是A中定义的成员,标准对限定名前缀的检查是独立进行的,和成员实际所属的类没有关联,只要前缀不符合要求,整个表达式就属于非法写法。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

