嵌套类的类内好友是否可以访问外部类成员?
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
成员受到保护,并且...,或B
的N
,该基类可在 R 上访问,并且在类
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,强调我的:
类的友元是一个函数或类,它被授予使用类中的私有和受保护成员名称的权限。类通过友元声明指定其友元(如果有)。这样的声明赋予朋友特殊的访问权限,但它们不会使被提名的朋友成为朋友阶层的成员。
当你有friend E f1()
时,这给了f1
使用B
的私有和受保护名称的权限,特别是。E
不是B
的私有或受保护的名称,它是B
也可以访问的名称。
这在概念上类似于[class.friend]/10:
友谊既不是遗传的,也不是传递的。
由于这意味着规则是f1
可以访问B
的东西,而B
可以访问A
的东西,因此f1
可以访问A
的东西。
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- 访问 PlatformIO 中的外部环境变量
- 如何在函数外部访问函数中局部变量的值?
- Windows C++静态库在初始化期间无法访问外部方法
- C++使用其他命名空间中的符号,而不使它们可从外部访问
- 从内部类访问外部公共成员
- 从不同的标头访问外部结构成员
- C 可以从继承链中访问外部会员
- 在lambda中访问外部范围名称,是G 或视觉范围或不正确的
- 如何使用LLVM访问外部结构?
- 使用线程控制访问外部API的对象
- 使用JNI访问外部本机功能
- 从外部函数访问外部结构属性
- 为什么局部类定义可以从同一函数访问外部静态变量
- 如何避免私有成员通过类对象访问外部单词
- 这段代码如何访问C++外部的局部变量
- 访问外部进程的内存
- 在c++中是否有办法访问外部作用域中的局部变量?
- 我如何使用OpenCV访问外部网络摄像头?
- 访问外部浮点数组时遇到问题