Modelo de class com amigo de class de modelo, o que realmente está acontecendo aqui?

Digamos que eu esteja criando uma class para uma tree binária, BT , e eu tenho uma class que descreve um elemento da tree, BE , algo como

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

Isso parece funcionar; No entanto, tenho dúvidas sobre o que está acontecendo embaixo.

Eu originalmente tentei declarar o amigo como

 template friend class BT; 

no entanto, parece necessário usar U (ou algo diferente de T ) aqui, por que isso acontece? Isso implica que qualquer BT particular é amigo de qualquer class BE específica?

A página da IBM sobre modelos e amigos tem exemplos de tipos diferentes de relacionamentos de amigos para funções, mas não para classs (e adivinhando que uma syntax ainda não convergiu na solução). Eu preferiria entender como obter as especificações corretas para o tipo de relação de amizade que desejo definir.

 template class BE{ template friend class BT; }; 

Não é permitido porque os parâmetros do modelo não podem sombrear um ao outro. Modelos nesteds devem ter nomes de parâmetros de modelo diferentes.


 template struct foo { template friend class bar; }; 

Isto significa que bar é um amigo de foo independentemente dos argumentos do template da bar . bar , bar , bar , e qualquer outra bar seria amiga do foo .


 template struct foo { friend class bar; }; 

Isso significa que bar é um amigo de foo quando o argumento do modelo da bar corresponde a foo ‘s. Apenas bar seria um amigo de foo .


No seu caso, friend class bar; deve ser suficiente.

Para fazer amizade com outra estrutura do mesmo tipo:

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

Com a saída da seguinte forma:

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

No template friend struct Foo; você não deve escrever T depois de typename / class caso contrário, isso causará um erro de sombreamento de parâmetro de modelo.

Não é necessário nomear os parâmetros para que você obtenha menos pontos de falha se refatorar:

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

No meu caso, esta solução funciona corretamente:

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

Espero que seja útil.