Шаблон класса с другом класса шаблонов, что на самом деле происходит здесь?
Скажем, я создаю класс для двоичного дерева 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 на шаблонах и друзья имеет примеры разных типов отношений друзей для функций, но не классов (и угадывание синтаксиса еще не сходилось на решении). Я бы предпочел понять, как правильно получить спецификации для типа отношений друзей, которые я хочу определить.
Ответы
Ответ 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;}
};
Я надеюсь, что это будет полезно.