class x
{
void xx() {}
};
class y
{
friend void x::xx();
};
This results in an error like
error: friend function 'xx' is a private member of 'x'
Why can't I declare a private member function to be a friend of another class?
class x
{
void xx() {}
};
class y
{
friend void x::xx();
};
This results in an error like
error: friend function 'xx' is a private member of 'x'
Why can't I declare a private member function to be a friend of another class?
The idea of making x::xx
private
is supposed to be that x::xx
is an implementation detail that other classes should not be relying on. It doesn't just mean that x::xx
cannot be called by other classes, it means, or rather it should mean, that e.g. renaming x::xx
to x::xy
shouldn't break anything other than the class itself, and the class's friends.
In your case, renaming x::xx
to x::xy
would cause class y
to have an error, even though it is not a friend of x
.
A way to avoid that is to make y
a friend of x
, so that y
can access x
's private
members. It can then declare x::xx
as a friend
.
(Note: the more direct answer to the question "Why does the compiler not allow this?" is "Because the standard does not allow this.", which naturally leads to the follow-up question "Why does the standard not allow this?". I'm attempting to answer that follow-up question.)
[class.friend]/9:
The reason is quite simple;
private
members shall obey a clear and definite rule:Allowing private members to be named in declarations inside unrelated classes would violate this rule: it enables another class to depend on an implementation detail without being explicitly allowed to. This becomes problematic, for instance, when changing a private member's name, type or signature, or removing it entirely; that's intended not to break the interface of that class.
This can be circumvented by making the entirety of
x
a friend ofy
:Demo.