A friend function can be declared in a class template either
as a single function shared by all classes created by the
template or as a template function that varies from class to
class within the class template. For example:
template<class T> class portfolio
{
//...
friend void taxes();
friend void transact(T);
friend portfolio<T>* invest(portfolio<T>*);
friend portfolio* divest(portfolio*); //error
// ...
};
In this example, each declaration has the following characteristics:
taxes()
is a single function that can access private and
protected members of any template class generated by the class
template. Note that taxes() is not a template function.
transact(T)
is a function template that declares a distinct function
for each class generated by the class template. The only private
and protected members that can be accessed by functions generated
from this template are the private and protected members of their
template class.
invest(portfolio<T>*)
is a function template whose return and argument types
are pointers to objects of type portfolio<T>. Each class
generated by the class template will have a friend function of
this name, and each such function will have a pointer to an
object of its own class as both its return type and its argument
type.
divest(portfolio*)
is an error because portfolio* attempts to point to a
class template. A pointer to a class template is undefined and
produces an error. This statement can be corrected by using the
syntax of the invest() function template instead.
Because all friend functions in this example are declared but
not defined, you could create a set of function templates to
define those functions that are implicitly template functions
(that is, all the valid functions except taxes()). The function
templates would then be used to instantiate the template
functions as required.