using声明能否引用不可访问基类的公有成员并使其公开?
关于通过限定名在using声明中恢复间接私有基类成员访问权限的问题
先看这段代码:
namespace mylib { struct A { int member1; typedef int member2; }; struct B : private A {}; struct C : B { using mylib::A::member1; using mylib::A::member2; }; }
在这段代码里,间接基类A因为B的私有继承,在C的作用域中是不可访问的,但我们可以通过限定名mylib::A::member1/member2直接引用A的成员。现在的问题是:能不能通过这种限定名在using声明里,把A的成员恢复为C中的公开访问权限?
目前不同编译器的处理结果不一致:
- Clang 和 EDG 接受这段代码
- GCC 和 MSVC 会拒绝编译
编译器分歧的核心逻辑
接受方(Clang、EDG)的判断逻辑
它们认为,using声明这里直接引用的是命名空间mylib中类A的公有成员,而不是把A当作C的间接基类来引用成员。A本身在全局命名空间mylib中是公开可见的,其成员member1和member2也是公有的,所以C作为普通类,完全有权通过限定名把这些成员引入自己的作用域,和B对A的私有继承关系无关。
拒绝方(GCC、MSVC)的判断逻辑
它们的核心观点是:C继承自B,而B私有继承了A,所以A是C的间接私有基类,在C的作用域中A整体是不可访问的。即使使用了mylib::A这样的限定名,using声明的本质还是试图引入基类成员,而由于基类A在C中不可访问,这种操作违反了继承访问权限的规则,因此不合法。
标准层面的解读
根据C++标准中关于using声明的规则,using声明既可以引入命名空间中的成员,也可以引入基类的成员。在这个场景中,关键在于using mylib::A::member1到底属于哪种情况:
- 如果是引入命名空间成员:
mylib::A::member1是命名空间mylib下的公有成员,C的using声明完全合法,因为命名空间的成员访问不受继承关系限制。 - 如果被判定为引入基类成员:由于
A作为C的间接基类不可访问,这种using声明就不合法。
从标准文本的严谨性来看,mylib::A是明确的命名空间限定类名,这里的using声明直接指向该类的公有成员,应该属于第一种情况,因此Clang和EDG的处理更符合标准的字面含义。
内容的提问来源于stack exchange,提问作者cpplearner
相关产品推荐
相关产品推荐

