Подтвердить что ты не робот

Шаблон класса с другом класса шаблонов, что на самом деле происходит здесь?

Скажем, я создаю класс для двоичного дерева BT, и у меня есть класс, который описывает элемент дерева BE, что-то вроде

template<class T> class BE {
    T *data;
    BE *l, *r;
public:
...
    template<class U> friend class BT;
};

template<class T> class BT {
    BE<T> *root;
public:
...
private:
...
};

Это, похоже, работает; однако у меня есть вопросы о том, что происходит под ним.

Я изначально пытался объявить друга как

template<class T> friend class BT;

однако, похоже, здесь нужно использовать U (или что-то другое, чем T), почему это? Означает ли это, что какой-либо конкретный BT является другом какого-либо конкретного класса BE?

Страница IBM на шаблонах и друзья имеет примеры разных типов отношений друзей для функций, но не классов (и угадывание синтаксиса еще не сходилось на решении). Я бы предпочел понять, как правильно получить спецификации для типа отношений друзей, которые я хочу определить.

4b9b3361

Ответ 1

template<class T> class BE{
  template<class T> friend class BT;
};

Не разрешено, потому что параметры шаблона не могут тень друг друга. Вложенные шаблоны должны иметь разные имена параметров шаблона.


template<typename T>
struct foo {
  template<typename U>
  friend class bar;
};

Это означает, что bar является другом foo, независимо от аргументов шаблона bar. bar<char>, bar<int>, bar<float>, и любые другие bar будут друзьями foo<char>.


template<typename T>
struct foo {
  friend class bar<T>;
};

Это означает, что bar является другом foo, когда аргумент bar template соответствует foo. Только bar<char> будет другом foo<char>.


В вашем случае friend class bar<T>; должно быть достаточно.

Ответ 2

Не нужно указывать параметры, чтобы вы получали меньше точек отказа, если рефакторинг:

     template <typename _KeyT, typename _ValueT> class hash_map_iterator{
       template <typename, typename, int> friend class hash_map;
       ...

Ответ 3

чтобы подружиться со структурой другого типа:

template<typename T>
struct Foo
{
  template<typename> friend struct Foo;
};

обратите внимание, что в template<typename> friend struct Foo; вам не следует писать T после typename/class; в противном случае это приведет к ошибке теневого копирования шаблона.

Ответ 4

В моем случае это решение работает правильно:

template <typename T>
class DerivedClass1 : public BaseClass1 {
  template<class T> friend class DerivedClass2;
private:
 int a;
};

template <typename T>
class DerivedClass2 : public BaseClass1 {
  void method() { this->i;}
};

Я надеюсь, что это будет полезно.