[英]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
實際上有效嗎?
我找到的相關標准件是:
嵌套類是成員,因此具有與任何其他成員相同的訪問權限。
雖然這並不意味着嵌套類的朋友擁有與嵌套類完全相同的權限。
對成員的訪問權限受成員命名的類的影響。 此命名類是查找和查找成員名稱的類。 當在
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.