繁体   English   中英

朋友 function 的成员访问控制在 C++ 中的 class 中定义

[英]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.

  1. 两个编译器之一中是否存在错误?
  2. 如果是,是哪一个?
  3. 不管前面问题的答案如何,这不是标准应该更好地形式化的东西吗?

这看起来像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 的私有和受保护成员? 实现在这一点上有所不同。

对于初学者 - 免责声明:这是我对标准的解释,即使我认为它是正确的,也不能确定它的真正含义。

tl;博士

  1. 是的。
  2. 国际海事组织铿锵++
  3. 如果你往下看,你会发现它的形式化得很好。

完整答案

话虽如此,我认为该标准有两个相关的引用。 首先是这样的:

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.

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