We have two class-templates: A and B, and a function-template f1(). Like this:
template< class T >
class A{};
template< class T >
class B
{
friend class A<T>; /* Expression 1 */
friend void f1( B<T> &b ); /* Expression 2 */
};
template< class T >
void f1( B<T> &b ) {}
int main()
{
A< int > a;
B< int > b;
f1( b );
return 0;
}
problem 1: expression 1 make the specialization of A with argument T a friend of the specialization of B with argument T. But how to make every specialization of A all friends of specialization of B?
problem 2: how to define f1 outside the class definition? the code like this will generate an error:
undefined reference to `f1(B<int>&)'
problem 3: how to make all f1()s (who can receive all specialization of B as arguments) friends of every specialization of B?
Problem 1:
Do you really want to do it? Do you want A<int>
to access B<float>
? Usually you don't, but if you really want:
template <typename U>
friend class A;
Problem 2:
The problem in 2 is that you are not making the instantiation of the f1
template a friend, but rather you are trying to make a non-templated free function f1
that takes a B<int>
your friend. The correct syntax to befriend a particular instantiation is cumbersome:
template <typename T> class B;
template <typename T> void f( B<T>& );
template <typename T>
class B {
friend void f<T>( B<T>& );
};
Problem 3:
To make all specializations of f1
a friend (again, do you really want this?), you can do the same approach as for the class template:
template <typename U>
friend void f1( B<U>& );
More on all those here