    With emi(bound friend)hi(friend: bound) class or function templates there
is a one-to-one mapping between the template arguments of the friend templates
and the template arguments of the class templates declaring them as
friends. In this case, the friends themselves are templates too. Here are the
various possibilities:
    itemization(
    it() A function template is a friend of a class template. In this case we
don't experience the problems we encountered with ordinary functions declared
as friends of class templates. Since the friend function template itself is a
template it may be provided with the required template arguments allowing it
to become the declaring class's friend. The various declarations are organized
like this:
    itemization(
    it() The class template declaring the bound template friend function is
defined;
    it() The (friend) function template is defined, now having access to all
the class template's (private) members.
        )
    The bound template friend declaration specifies the required template
arguments immediately following the template's function name. Without the
template argument list affixed to the function name it would remain an
ordinary friend function. Here is an example showing a bound friend to create
a subset of the entries of a dictionary. For real life examples, a dedicated
function object returning tt(!key1.find(key2)) is probably more useful.  For
the current example, tt(operator==) is acceptable:
        verbinclude(//FUNCTION examples/boundfriends.cc)

    it() By declaring a full class template as a class template's friend, all
members of the friend class may access all private members of the class
declaring the friend. As the friend class only needs to be declared, the
organization of the declaration is much easier than when function templates
are declared as friends. In the following example a class tt(Iterator) is
declared as a friend of a class tt(Dictionary). Thus, the tt(Iterator) is able
to access tt(Dictionary)'s private data. There are some interesting points to
note here:
        itemization(
        it() To declare a class template as a friend, that class only needs to
be declared as a class template before it is declared as a friend:
            verbinclude(//CLASS1 examples/boundfriends.cc)
        it() However, members of the friend class may already be used, even
though the compiler hasn't seen  the friend class's interface yet:
            verbinclude(//CLASS2 examples/boundfriends.cc)
        it() Of course, the friend class's interface must eventually be seen
by the compiler. Since it's a support class for tt(Dictionary) it can safely
define a tt(std::map) data member that is initialized by the friend class's
constructor. The constructor may then access the tt(Dictionary)'s private data
member tt(d_dict):
            verbinclude(//CLASS3 examples/boundfriends.cc)
        it() The tt(Iterator) member tt(begin) may return a tt(map)
iterator. Since the compiler does not know what the instantiation of the map
looks like, a tt(map<Key, Value>::iterator) is a template subtype. So it
cannot be used as-is, but it must be prefixed by
tt(typename) (see the function tt(begin)'s return type in the next example):
            verbinclude(//CLASS4 examples/boundfriends.cc)
        )

    it() In the previous example we might decide that only a tt(Dictionary)
should be able to construct an tt(Iterator) (maybe because we conceptually
consider tt(Iterator) to be a sub-type of tt(Dictionary)). This is easily
accomplished by defining tt(Iterator)'s constructor in its private section,
and by declaring tt(Dictionary) to be a friend of tt(Iterator). Consequently,
only a tt(Dictionary) can create an tt(Iterator). By declaring the constructor
of a em(specific) tt(Dictionary) type as a friend of tt(Iterator)'s we declare
a em(bound) friend. This ensures that only that particular type of
tt(Dictionary) can create tt(Iterator)s using template parameters identical to
its own. Here is how it's done:
        verbinclude(//CLASS3a examples/boundfriends.cc)
    In this example, tt(Dictionary)'s constructor is tt(Iterator)'s
friend. The friend is a template member. Other members can be declared as
a class's friend as well. In those cases their prototypes must be used, also
specifying the types of their return values. Assuming that
        verb(
std::vector<Value> sortValues()
        )
    is a member of tt(Dictionary) then the matching bound friend declaration
is:
        verb(
friend std::vector<Value> Dictionary<Key, Value>::sortValues();
        )

    it() A class template may define free members, which should have access to
the data of instantiations of the class template, but only for matching
types. An example is a class template for which the free member tt(operator==)
must be available. If this is required for a template tt(ClassTemplate),
requiring a tt(typename Type) template type argument, then
a free member 
        verb(
    template<typename Type>
    bool operator==(ClassTemplate<Type> const &lhs, 
                    ClassTemplate<Type> const &rhs);
        )
    must have been declared prior to tt(ClassTemplate)'s interface
itself. Within the class interface tt(operator==) may then be declared as a
friend, specifying tt(operator==) as a specialized function template (note the
tt(<>) following the function name) like this:
        verb(
    template <typename Type>
    class ClassTemplate
    {
        friend  bool operator==<>(ClassTemplate<Type> const &lhs, 
                                ClassTemplate<Type> const &rhs);
        ...
    };
        )
    Now that the class has been declared, tt(operator==)'s implementation may
follow. 
    )

    Finally, the following example can be used as a prototype for
situations where bound friends are useful:
        verb(
    template <typename T>   // a function template
    void fun(T *t)
    {
        t->not_public();
    };
    template<typename X>    // a free member function template
    bool operator==(A<X> const &lhs, A<X> const &rhs);
    template <typename X>   // a class template
    class A
    {                       // fun() is used as friend bound to A,
                            // instantiated for X, whatever X may be
        friend void fun<A<X>>(A<X> *);
                            // operator== is a friend for A<X> only
        friend  bool operator==<>(A<X> const &lhs, A<X> const &rhs);

        int d_data = 10;

        public:
            A();

        private:
            void not_public();
    };
    template <typename X>
    A<X>::A()
    {
        fun(this);
    }
    template <typename X>
    void A<X>::not_public()
    {}
    template<typename X>    // may access lhs/rhs's private data
    bool operator==(A<X> const &lhs, A<X> const &rhs)
    {
        return lhs.d_data == rhs.d_data;
    }

    int main()
    {
        A<int> a;

        fun(&a);            // fun instantiated for A<int>.
    }
        )








