C++03 のfriend宣言に以下のような制限があるため
識別子がtypedef-nameまたはtemplate type-parameterになる場合、elaborated-type-specifierは不適格です。
以下の friend 宣言は不適格になります。
template <class T> class X { friend class T; // エラー!friend宣言にテンプレートパラメータを指定した };
template <class Allocator> class X { friend class Allocator::template rebind<X>::other; // エラー!friend宣言にtypedef名を指定した };
C++0x では、 friend T; のようにすることで、テンプレートパラメータやtypedef名であっても
friendにすることができるようになります。
template <class T> class X { friend T; // OK };
template <class Allocator> class X { friend typename Allocator::template rebind<X>::other; // OK };
N1520 Extended friend Declarations
N1791 Extended friend Declarations (Rev. 3)