バイナリツリー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ページには、クラスではなく関数のフレンド関係の異なるタイプの例があります(そして、構文の推測はまだソリューションに収束していません)。定義したい友人関係のタイプに合った仕様を取得する方法を理解したいと思います。
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
はfoo
のフレンドになります。 bar<char>
のみがfoo<char>
の友達になります。
あなたの場合、friend class bar<T>;
で十分です。
別の同じタイプの構造体と友達になるには:
#include <iostream>
template<typename T_>
struct Foo
{
// Without this next line source.value_ later would be inaccessible.
template<typename> friend struct Foo;
Foo(T_ value) : value_(value) {}
template <typename AltT>
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<int> foo1(5);
Foo<std::string> foo2("banana");
foo1.display(foo2);
return 0;
}
出力は次のとおりです。
My value is 5 and my friend's value is banana.
template<typename> friend struct Foo;
T
/typename
の後にclass
と書くべきではありません。そうしないと、テンプレートパラメータシャドウエラーが発生します。
パラメータを指定する必要はありませんので、リファクタリングする場合、失敗点が少なくなります。
template <typename _KeyT, typename _ValueT> class hash_map_iterator{
template <typename, typename, int> friend class hash_map;
...