对受保护嵌套类的友元访问

发布于 2024-09-16 09:39:43 字数 370 浏览 4 评论 0原文

我有以下 C++ 代码:

class A {
 protected:
  struct Nested {
    int x;
  };
};

class B: public A {
  friend class C;
};

class C {
  void m1() {
    B::Nested n; // or A::Nested
  }
};

使用 g++ 4.4 编译此代码片段,无论我在 m1 中使用 B::Nested 还是 A::Nested 都没有什么区别。 Clang 接受 B::Nested,但如果我 A::Nested 则不会编译。这是 g++ 或 clang 中的错误吗?

I have the following C++ code:

class A {
 protected:
  struct Nested {
    int x;
  };
};

class B: public A {
  friend class C;
};

class C {
  void m1() {
    B::Nested n; // or A::Nested
  }
};

Compiling this snippet with g++ 4.4, it does not make a difference whether I use B::Nested or A::Nested in m1. Clang accepts B::Nested, but does not compile if I A::Nested. Is that a bug in g++ or in clang?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

筑梦 2024-09-23 09:39:43

根据标准,GCC 是正确的,而 Clang 是错误的。上面写着 11.2/4

当在类 N 中命名时,成员 m 是可访问的,如果

  • m 作为 N 的成员受到保护,并且引用发生在 N 类的成员或友元中,或者发生在从 N 派生的类 P 的成员或友元中,其中 m 作为 P 的成员是私有的或受保护的

这是此 Clang 错误报告的主题,它阻止 Clang 构建 Qt: http://llvm.org/bugs/show_bug.cgi?id=6840。一位 Clang 人说

事实上,我有意还没有实现这个规则。它是一个
起草错误或可怕的错误。它使整个“受保护”变得中性
说明符,它使代码的格式良好依赖于
完全不相关的类的存在,会给
实现,并且在模板存在的情况下它在形式上是不可判定的。

According to the Standard, GCC is correct and Clang is wrong. It says at 11.2/4

A member m is accessible when named in class N if

  • m as a member of N is protected, and the reference occurs in a member or friend of class N, or in a member or friend of a class P derived from N, where m as a member of P is private or protected

This is subject of this Clang bugreport, which prevents Clang from building Qt: http://llvm.org/bugs/show_bug.cgi?id=6840 . One Clang guy says

Actually, I intentionally haven't implemented this rule yet. It is either a
drafting error or a horrible mistake. It neuters the entire 'protected'
specifier, it makes the well-formedness of code dependent on the
existence of completely unrelated classes, it imposes high costs on the
implementation, and it's formally undecidable in the presence of templates.

地狱即天堂 2024-09-23 09:39:43

在 C++ 中,友元是不可传递的。你朋友的朋友不一定是我的朋友。

通过在 A 中使 Nested 受保护,您表明所有子类都可以使用此元素,但不允许其他人使用它。你可以认为这是一种朋友。 A 使所有子类在访问嵌套结构方面成为朋友。

现在B使C成为朋友,但这并不意味着C也是A的朋友。所以C应该无权访问Nested。

但是:该行为从 C++03 开始​​发生了变化。在 C++03 中,嵌套类是封闭类的完整成员,因此具有完全访问权限。友谊仍然是不可传递的,但现在成员访问是可传递的。

您可能需要查看 http: //www.rhinocerus.net/forum/language-c-moderated/578874-friend-transitive-nested-classes.html,它解释了类似的问题。

In C++ friends are not-transitive. Friends of your friends are not necessarily my friends.

By making Nested protected in A, you indicate that all subclasses may use this element, but nobody else is allowed to use it. You could consider this is a kind of friend. A makes all subclasses friend regarding access to the Nested struct.

Now B makes C a friend, but this does not mean that C is also a friend of A. So C should have no access to Nested.

BUT: the behavior is changed from C++03. In C++03, a nested class is a full member of the enclosing class and so has full access rights. Friendship is still NOT transitive, but now member access is.

You may want to look at http://www.rhinocerus.net/forum/language-c-moderated/578874-friend-transitive-nested-classes.html, which explains a similar problem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文