[英]Member access control for friend function defined inside class in C++
我知道下面的 C++ 代码片段应该在g
的定义中产生错误,因为ptx
是私有的,不能在那里访问。
class P {
class T {
int x;
friend class P;
};
T t;
friend void g(P &p);
};
void g(P &p) { p.t.x = 42; }
让我困惑的是下一个片段。 不同之处仅在于朋友 function g
的定义现在出现在class P
内部。
class P {
class T {
int x;
friend class P;
};
T t;
friend void g(P &p) { p.t.x = 42; }
};
Clang++(6.0.0-1ubuntu2 和 Apple 版本 clang-1100.0.33.8)编译后者没有错误,而 GNU C++ (7.5.0-3ubuntu1~18.04) 产生与前一个片段相同的错误。
我了解在后一种情况下定义的 function g
与在前一种情况下定义的 scope 不同(参见相关问题和较早的较长讨论),并且仅通过 ADL 可见。 但我认为我在这里问的是不同的:class T
中的声明friend class P
是否应该扩展到朋友 function g
的主体?
C++ 标准(最近的草案中的 §11.3 或 §11.9.3)的相关部分指出:
7...在 class 中定义的朋友 function 在(词法)scope 的 ZA2F2ED4F28EBC2CBB4C21 中定义。 一个朋友function定义在class之外是不是(6.5.1)。
因此,我了解 Clang++ 和 GNU C++ 对“词法范围”的含义有不同的解释(另请参见上一个相关问题的答案)。 Clang++ seems to compile g
as if it were a friend of class T
, probably because it's in the lexical scope of class P
which is a friend of class T
, whereas GNU C++ does not.
这看起来像CWG1699 (仍处于打开状态)。
1699. 与 class 成为朋友是否会成为其朋友?
根据 14.3 [class.friend] 第 2 段,
将 class 声明为朋友意味着来自 class 授予友谊的私有成员和受保护成员的名称可以在结识的 ZA2F2ED4F8EBC2CBB4C21A29DC40AB61 的基本说明符和成员声明中访问
friend
声明是一个成员声明,但不清楚在朋友声明中授予友谊的程度。 例如:class c { class n {}; friend struct s; }; struct s { // #1 and #2 are not relevant for this question friend void f() { c::n(); } // #3 };
特别是,如果在 class 定义中定义了一个朋友 function,如 #3 中,它的定义是否可以访问友好的 class 的私有和受保护成员? 实现在这一点上有所不同。
对于初学者 - 免责声明:这是我对标准的解释,即使我认为它是正确的,也不能确定它的真正含义。
话虽如此,我认为该标准有两个相关的引用。 首先是这样的:
11.9 会员访问控制
1 class 的成员可以是
(1.1) - 私人; 也就是说,它的名字只能被声明它的class的成员和朋友使用。
第二个是:
11.9.3 朋友 [class.friend]
1 class 的朋友是 function 或 class 被授予使用来自 ZA41F2ED49DCEBC2C02 的私有和受保护成员名称的权限。 class 通过友元声明指定其友元(如果有)。 这样的声明赋予朋友特殊的访问权限,但它们不会使指定的朋友成为友好 class 的成员。
从这两个可以推断出一些事情。 但最重要的是,即使是内联好友也无法访问已成为好友的 class 内部定义的 class 的私有成员。 为什么? 因为它既不是嵌套 class 的成员也不是朋友。 由此看来,g++ 就在这里。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.