C++中使用`using`公开私有基类名称

11
在某些结构体 D 通过 B 私有地继承了另一个结构体 A,并且第二次通过 C 公开地继承,是否允许在 D 中编写 using B::A
struct A {};
class B : A {};
struct C : A {};
struct D : B, C { 
    using B::A;  //ok in GCC, error in Clang
};

该程序被GCC接受,但是Clang却打印出错误信息:
error: 'A' is a private member of 'A'

演示:https://gcc.godbolt.org/z/5jeqrzorE

using B::A 只需公开从 D 注入的类名 A。一方面,A 已经可以在 D 中使用(因此 GCC 接受它),但另一方面,AB 中是私有的(因此 Clang 拒绝它)。哪个编译器是正确的?

2个回答

1

[class.access.base]/5:

成员的访问受到命名它的类的影响。该命名类是在其作用域内进行搜索以找到该成员的类。
在这种情况下,命名类是 B。由于 A 作为 B 的成员是私有的,在 D 中无法访问,导致“using-declaration”不合法。

-1
在这种情况下,会存在某些歧义。当检查A时,需要忽略类的查找。GCC应该是正确的,因为B::A和C::A引用了来自D的同一个A。 即使添加了“using C::A”,clang也无法检测到错误。
struct A {};
struct B :  A {};
struct C : A {};
struct D : C, B { 
    using B::A;  //ok in Clang, error in GCC
    using C::A;
};

https://timsong-cpp.github.io/cppwp/namespace.udecl#1


1
你在代码中用struct B替换了class B。这将把继承类型从私有改为公有。 - Fedor
1
我只是想展示在那种情况下clang的行为是不正确的。 - nhatnq

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接