i think often friend function usage its a matter of readability. For example next overloaded operator looks symmetrically and this may be good for code reader.
friend const X operator+(const X&, const X&);inline const X operator+(const X& arg1, const X& arg2){ X r; r.x = arg1.x + arg2.x; return r;}
But main point its their ability to access private data of two different classes.