как связать два шаблонных класса в дружбе многие ко многим? - PullRequest
1 голос
/ 31 января 2011

предположим, что у меня есть следующие два класса шаблонов:

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

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

как я могу связать их в дружбе многие ко многим. например, добавление метода в First, который печатает b объекта параметра Second.

мой вопрос ясен?

Ответы [ 3 ]

3 голосов
/ 31 января 2011
template <typename T>
class First {
   int a;
   template<typename> friend class Second;
};
template <typename T>
class Second
{
   int b;
   template<typename> friend class First;
};

Это позволит каждому First<T> получить доступ к внутренним частям каждого Second<U>. Теперь, пока это техническое решение, вы можете подумать, является ли проект с циклическими зависимостями и открытием внутреннего для любого экземпляра другого класса лучшим решением для вашей конкретной проблемы.

Кстати, если вы хотите предоставить First<int> доступ только к Second<int> (а не Second<double>), вы можете сделать это следующим образом:

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>;
};

В этой второй версии вам требуется предварительное объявление шаблона Second, прежде чем подружиться с конкретным экземпляром, но это позволяет вам предоставить доступ к внутренним элементам класса только конкретному экземпляру.

0 голосов
/ 31 января 2011

При условии, что вы понимаете защиту, является ли вопрос предварительной декларации шаблонов:

#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);
}
0 голосов
/ 31 января 2011

Вы можете начать с объявления каждого класса:

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

И теперь оба класса будут знать о другом в своих определениях.Вы можете объявить их там как друзей, если вам нужно.

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

и наоборот.

Вы также можете реализовать тела функций в определениях классов, если им нужно видеть друг друга.детали, т. е. они не могут использовать копию «предварительного заявления».

...