众所周知,在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之外)?
注意:如果友元函数只是在类中声明并在外部实现,则Clang和GCC都会拒绝该代码。
operator!=()
(不是Inner1
的友元)访问Inner1
的私有成员。一种正确提供访问权限的方法(不依赖于所有编译器都像clang一样存在缺陷)是将operator!=()
作为Inner2
的成员而不是friend
- 因为Inner2
已经是一个friend
,它的成员将正确地访问Inner1
实例的成员。 - Peter