    Friend hi(friend) functions are normally constructed as em(support) (free)
functions of a class that cannot be implemented and declared as class
members. The insertion operator for output streams is a well known
example. Friend classes are most often seen in the context of nested classes.
Here the inner class declares the outer class as its friend (or the other way
around). Again we see a support mechanism: the inner class is constructed to
support the outer class.

    Like ordinary classes, class templates may declare other functions and
classes as their friends. Conversely, ordinary classes may declare template
classes as their friends. Here too, the friend is constructed as a special
function or class augmenting or supporting the functionality of the declaring
class. Although the tt(friend) keyword can be used by any type of class
        hi(class template: using friend)
        hi(friend: in class templates)
    (ordinary or template) when using class templates the following cases
should be distinguished:
    itemization(
    it() A class template may declare an ordinary function or class as its
friend. This is a common friend declaration, such as the insertion operator
for tt(ostream) objects.
    it() A class template may declare another function template or class
template as its friend. In this case, the friend's template parameters may
have to be specified.

    If the actual values of the friend's template parameters em(must) be equal
to the template parameters of the class declaring the friend, the friend is
said to be a emi(bound friend)hi(friend: bound) class or function template. In
this case the template parameters of the template specifying the tt(friend)
declaration determine (em(bind)) the values of the template parameters of the
friend class or function. Bound friends result in a one-to-one correspondence
between the template's parameters and the friend's template parameters.
    it() In the most general case a class template may declare another
function template or class template to be its friend, irrespective of the
friend's actual template arguments.

    In this case an emi(unbound friend) class or function template is
declared. The template parameters of the friend class or function template
remain to be specified and are not related in some predefined way to the
template parameters of the class declaring the friend. If a class template has
data members of various types, specified by its template parameters and
another class should be allowed direct access to these data members we want to
specify any of the current template arguments when specifying such a
friend. Rather than specifying multiple bound friends, a single generic
(unbound) friend may be declared, specifying the friend's actual template
parameters only when this is required.
    it() The above cases, in which a template is declared as a friend, may
also be encountered when ordinary classes are used:
        itemization(
        it() The ordinary class declaring ordinary friends has already been
covered (chapter ref(Friends)).
        it() The equivalent of bound friends occurs if an ordinary class
specifies specific actual template parameters when declaring its friend.
        it() The equivalent of unbound friends occurs if an ordinary class
declares a generic template as its friend.
        )
    )
