簡體   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