Modèle de classe avec un ami de classe de modèle, qu’est-ce qui se passe vraiment ici?

Disons que je crée une classe pour un arbre binary, BT , et j’ai une classe qui décrit un élément de l’arbre, BE , quelque chose comme

 template class BE { T *data; BE *l, *r; public: ... template friend class BT; }; template class BT { BE *root; public: ... private: ... }; 

Cela semble fonctionner; Cependant, j’ai des questions sur ce qui se passe en dessous.

J’ai d’abord essayé de déclarer l’ami comme

 template friend class BT; 

Cependant, il semble nécessaire d’utiliser U (ou autre chose que T ) ici, pourquoi est-ce? Est-ce que cela implique qu’un BT particulier est ami avec une classe BE particulière?

La page IBM sur les modèles et les amis contient des exemples de différents types de relations d’amitié pour les fonctions mais pas pour les classes (et deviner une syntaxe n’a pas encore convergé sur la solution). Je préférerais comprendre comment obtenir les spécifications correctes pour le type de relation d’amis que je souhaite définir.

 template class BE{ template friend class BT; }; 

N’est pas autorisé, car les parameters du modèle ne peuvent pas se chevaucher. Les modèles nesteds doivent avoir des noms de parameters de modèle différents.


 template struct foo { template friend class bar; }; 

Cela signifie que la bar est un ami de foo indépendamment des arguments de modèle de la bar . bar , bar , bar , et toute autre bar serait amie de foo .


 template struct foo { friend class bar; }; 

Cela signifie que la bar est un ami de foo lorsque l ‘argument du template de la bar correspond à celui de foo . Seule la bar serait un ami de foo .


Dans votre cas, la friend class bar; devrait être suffisant.

Pour se lier à une autre structure de même type:

 #include  template struct Foo { // Without this next line source.value_ later would be inaccessible. template friend struct Foo; Foo(T_ value) : value_(value) {} template  void display(AltT &&source) const { std::cout << "My value is " << value_ << " and my friend's value is " << source.value_ << ".\n"; } protected: T_ value_; }; int main() { Foo foo1(5); Foo foo2("banana"); foo1.display(foo2); return 0; } 

Avec la sortie comme suit:

 My value is 5 and my friend's value is banana. 

Dans le template friend struct Foo; vous ne devriez pas écrire T après typename / class sinon cela provoquerait une erreur d’ombrage param modèle.

Il n’est pas nécessaire de nommer les parameters pour obtenir moins de points de défaillance en cas de refactoring:

  template  class hash_map_iterator{ template  friend class hash_map; ... 

Dans mon cas, cette solution fonctionne correctement:

 template  class DerivedClass1 : public BaseClass1 { template friend class DerivedClass2; private: int a; }; template  class DerivedClass2 : public BaseClass1 { void method() { this->i;} }; 

J’espère que ce sera utile.