2011-01-31 1 views
1

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

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

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

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

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

+0

Нет, это не ясно, что вы имеете в виду. Вы хотите, чтобы каждый класс был другом другого? – CashCow

+0

Он называется _class template_, потому что это шаблон, из которого вы создаете классы. Это не класс, и вы не можете его использовать, как если бы это был класс: 'class mine: public First {};' fail, потому что 'First' не является классом. 'Первый ', OTOH, является и может быть использован как таковой. – sbi

ответ

3
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

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

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

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

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

и то же самое в обратном порядке.

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

0

Предполагая, что вы понимаете защиту, является вопрос опережающего объявления шаблонов:

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