how to link two template classes in many-to-many friendship?

695 views Asked by At

assume that I have the following two template classes :

template <class _A>
class First
{
private:
    int a;
};

template <class _B>
class Second
{
private:
    int b;
};

how can I link them in many-to-many friendship. for example, adding a method in First that prints b of a parameter object of Second.

is my question clear?

3

There are 3 answers

0
David Rodríguez - dribeas On BEST ANSWER
template <typename T>
class First {
   int a;
   template<typename> friend class Second;
};
template <typename T>
class Second
{
   int b;
   template<typename> friend class First;
};

This will enable every First<T> to access the internals of every Second<U>. Now, while this is the technical solution, you might want to consider whether a design with cyclic dependencies and opening up the internal to any instantiation of the other class is the best solution to your particular problem.

BTW, if you only want to grant First<int> access to Second<int> (and not Second<double>) you can do that like so:

template <typename> class Second;
template <typename T>
class First {
   int a;
   friend class Second<T>; // only befriend the same instantiation
};
template <typename T>
class Second {
   int b;
   friend class First<T>;
};

In this second version you need the forward declaration of the Second template before befriending a particular instantiation, but this allows you to grant access to the internals of the class only to a particular instantiation.

0
CashCow On

You could start off with a declaration of each class:

template< typename T > class First;
template< typename T > class Second;

And now both classes will know about the other one in their definitions. You can declare them as friends there if you need to.

template< typename T > class First
{
   template< typename U> friend class Second;
};

and the same in reverse.

You can also implement function bodies under the class definitions if they need to see each other's details, i.e. they cannot use a "forward declaration" copy.

0
Keith On

Assuming you understand protection, is the issue forward declaration of templates:

#include <iostream>

template <class _B> class Second; // Forward declare

template <class _A>
class First
{
public:
    template<class _B>
    void print(const Second<_B>& b)
    {
        std::cout << b.b << std::endl;
    }
    int a;
};

template <class _B>
class Second
{
public:
    int b;
};

void testIt()
{
    Second<double> sd;
    First<int >fi;
    fi.print<double>(sd);
}