This builds in GCC, but not MSVC. It seems that GCC can access private members of outer class from a friend function in a nested class, but MSVC cannot. Why is this?
template <typename T>
class Outer
{
public:
struct Inner {
friend bool operator==(const Inner& a, const Inner& b) {
return a.outer_.private_member_ == b.outer_.private_member_;
}
// Both compilers are happy this if uncommented
// bool operator==(const Inner& other) {
// return outer_.private_member_ == other.outer_.private_member_;
// }
private:
Outer<T>& outer_;
};
friend struct Iterator;
private:
int private_member_;
};
bool test(Outer<int>::Inner A, Outer<int>::Inner B)
{
return A == B;
}
The program is ill-formed as per class.nest#4 which states:
Like a member function, a friend function ([class.friend]) defined within a nested class is in the lexical scope of that class; it obeys the same rules for name binding as a static member function of that class ([class.static]), but it has no special access rights to members of an enclosing class.
(emphasis mine)
This means that the overloaded operator==
in your example is not allowed to access the private data member named private_member_
of the enclosing class Outer<T>
.
To make this well-formed you can make operator==(const Inner&, const Inner&)
a friend of Outer<T>
. Demo
Here is the gcc bug:
GCC accepts private member access of enclosing class through friend function of inner class