C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 14:
[14.3] What are some advantages/disadvantages of using friend functions?

They provide a degree of freedom in the interface design options.

Member functions and friend functions are equally privileged (100% vested). The major difference is that a friend function is called like f(x), while a member function is called like x.f(). Thus the ability to choose between member functions (x.f()) and friend functions (f(x)) allows a designer to select the syntax that is deemed most readable, which lowers maintenance costs.

The major disadvantage of friend functions is that they require an extra line of code when you want dynamic binding. To get the effect of a virtual friend, the friend function should call a hidden (usually protected) virtual member function. This is called the Virtual Friend Function Idiom. For example:

class Base {
public:
  friend void f(Base& b);
  ...
protected:
  virtual void do_f();
  ...
};

inline void f(Base& b)
{
  b.do_f();
}

class Derived : public Base {
public:
  ...
protected:
  virtual void do_f();  // "Override" the behavior of f(Base& b)
  ...
};

void userCode(Base& b)
{
  f(b);
}
The statement f(b) in userCode(Base&) will invoke b.do_f(), which is virtual. This means that Derived::do_f() will get control if b is actually a object of class Derived. Note that Derived overrides the behavior of the protected virtual member function do_f(); it does not have its own variation of the friend function, f(Base&).