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
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.