繁体   English   中英

嵌套类的同类朋友是否可以访问外部类成员?

[英]Does an in-class friend of a nested class have access to outer class members?

clang ++,g ++和MSVC 对此代码不同意

class A {
private:
    enum class E { NO, YES };
    class B {
    private:
        friend E f1() { return E::YES; }
        // friend E f2();
    };
};

// A::E f2() { return A::E::YES; }

int main() {}

clang ++接受如图所示的代码。 g ++和MSVC在f1中抱怨A::E无法访问。 如果函数f2被取消注释,则所有三个编译器都在其定义中抱怨A::E是不可访问的。

f1实际上有效吗?

我找到的相关标准件是:

[class.access.nest]

嵌套类是成员,因此具有与任何其他成员相同的访问权限。

虽然这并不意味着嵌套类的朋友拥有与嵌套类完全相同的权限。

[class.access.base] / 5

对成员的访问权限受成员命名的类的影响。 此命名类是查找和查找成员名称的类。 当在N类中命名时,可以在R点访问成员m

  • m作为N的成员是公共的,或

  • m作为N的成员是私有的, R出现在N类的成员或朋友中,或者

  • m作为N的成员受到保护,并且......,或

  • 存在可在R处访问的N的基类B ,并且当在类B命名时, m可在R处访问。

因此f2是无效的,因为A::E的命名类肯定是A ,没有涉及基类,并且f2的定义不是A的成员或朋友,并且不会“出现在”成员或朋友中A

f1中,不合格E的命名类也是A ([basic.lookup.unqual]表示首先在A::B类中查找名称E ,但在那里找不到它,因此在A类中进行查找,找到成员。)但我想那个大问题是, f1的定义是否“发生在” A的成员中? 该成员如果是,则必须是class A::B

我认为gcc和msvc是对的。

来自[class.friend] / 1 ,强调我的:

一类的一个朋友是给从类中使用private和protected成员名称权限的函数或类。 类通过朋友声明指定其朋友(如果有的话)。 这些声明给予朋友特殊的访问权限,但他们不会成为朋友级的指定朋友。

当你有friend E f1() ,它赋予f1使用B的私有和受保护名称权限。 E不是B的私有或受保护名称,它也是B只能访问的名称。


这在概念上类似于[class.friend] / 10

友谊既不是遗传也不是传递。

因为它意味着规则是f1可以访问B的东西,并且B可以访问A的东西,因此f1可以访问A的东西。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM