访问好友类的私有成员的好友函数

A friend function accessing a private member of a friend class

提问人:Amir Kirsh 提问时间:5/28/2021 最后编辑:Amir Kirsh 更新时间:5/31/2021 访问量:341

问:

2019年特拉维夫欧洲歌唱大赛捷克歌曲之后

众所周知,在 C++ 中,朋友的朋友不是(自动)朋友。

但是,Clang 在 GCC 和 MSVC 的以下代码上有所不同:

class A {
public:    
    // forward declaration
    class Inner2;

private:
    class Inner1 {
        char foo;
        friend class Inner2;
    };
public:
    class Inner2 {
        Inner1 i;
    public:
        bool operator==(Inner2 other) {
            return i.foo == other.i.foo; // OK by GCC, Clang and MSVC++
        }
        friend bool operator!=(Inner2 a, Inner2 b) {
            return a.i.foo != b.i.foo; // Clang accepts, GCC and MSVC++ reject
        }
    };
};

代码: https://godbolt.org/z/rn48PTe1Y

哪一个是正确的? 如果 Clang 因为过于宽容而错了,那么允许访问的最佳方式是什么(除了提供公共 getter?


注意:如果 friend 函数只是在类中声明并在外部实现,则 Clang 和 GCC 都会拒绝代码

C++ 好友 friend-function friend-class

评论

0赞 Peter 5/29/2021
Clang 是错误的,因为它允许 - 它不是 的朋友 访问 的私人成员。正确提供访问权限的一种方法(它不像 clang 那样依赖于所有编译器都有错误)是使 a 的成员而不是 - 因为已经是 a,它的成员将正确地访问 的实例的成员。operator!=()Inner1Inner1operator!=()Inner2friendInner2friendInner1

答:

6赞 Amir Kirsh 5/31/2021 #1

这似乎是 clang 中的已知缺陷,错误 ID #11515,已经在 2011 年报告,但显然仍未修复。

一个更简单的示例,可以编译,并且不应该编译(来自上面的错误报告):

class A {
  int n;
  friend struct B;
};

struct B {
  friend int get(A &a) {
    return a.n; // clang accepts, and should reject
  }
};

https://godbolt.org/z/r78Pazoqj