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 thatx::xx
is an implementation detail that other classes should not be relying on. It doesn't just mean thatx::xx
cannot be called by other classes, it means, or rather it should mean, that e.g. renamingx::xx
tox::xy
shouldn't break anything other than the class itself, and the class's friends.In your case, renaming
x::xx
tox::xy
would cause classy
to have an error, even though it is not a friend ofx
.A way to avoid that is to make
y
a friend ofx
, so thaty
can accessx
'sprivate
members. It can then declarex::xx
as afriend
.(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.