以下代码是否符合C ++标准?
struct B
{
protected:
struct Type {};
};
struct D : B, B::Type
{};
int main()
{
D d;
return 0;
}
我在Compiler Explorer上尝试过。MSVC(VS 2017 RTW)接受。gcc(7.3)和clang(6.0.0)拒绝它。
该代码符合标准,自C ++ 11起,但不在C ++ 03中。
C ++ 11至C ++ 17在成员访问控制[class.access]部分的介绍中说:
子句[class.access]中的所有访问控制都会影响从特定实体的声明中访问类成员名称的能力,包括在要声明的实体名称之前的声明部分,如果该实体是类,则类成员的定义出现在类的member-specification之外。
在那些相同的Standard版本中,下面的示例非常类似于您的问题,但更加棘手:
[例:
class A { ... protected: struct B { }; }; ... struct D: A::B, A { };
...由于是从派生的,因此
A::B
用作基本说明符的格式D
很正确A
,因此必须推迟对基本说明符的检查,直到看到整个基本说明符列表为止。-结束示例]
但是我看到的结果与您相同:无论-std=
我给出什么参数,g ++和clang ++都拒绝这些程序。这是一对编译器错误。
C ++ 03拥有了这个,而不是我上面引用的第一段:
子句[class.access]中的所有访问控制都会影响从特定范围访问类成员名称的能力。对出现在成员类定义之外的类成员的定义中使用的名称的访问控制完成,就好像整个成员定义都出现在成员类的范围内一样。
类定义的基本说明符不在该类的范围内,因此C ++ 03不允许将受保护的名称或私有名称用作派生类的基类名称,否则该派生类可以访问该名称。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句