web-dev-qa-db-ja.com

テンプレートクラスの友人とクラステンプレート、実際に何が起きているのでしょうか?

バイナリツリー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ページには、クラスではなく関数のフレンド関係の異なるタイプの例があります(そして、構文の推測はまだソリューションに収束していません)。定義したい友人関係のタイプに合った仕様を取得する方法を理解したいと思います。

71
Michael Conlen
template<class T> class BE{
  template<class T> friend class BT;
};

テンプレートパラメータは互いにシャドウできないため、許可されません。ネストされたテンプレートには、異なるテンプレートパラメータ名が必要です。


template<typename T>
struct foo {
  template<typename U>
  friend class bar;
};

これは、barのテンプレート引数に関係なく、foobarのフレンドであることを意味します。 bar<char>bar<int>bar<float>、およびその他のbarfoo<char>の友達になります。


template<typename T>
struct foo {
  friend class bar<T>;
};

つまり、barのテンプレート引数がfooに一致する場合、barfooのフレンドになります。 bar<char>のみがfoo<char>の友達になります。


あなたの場合、friend class bar<T>;で十分です。

97
Pubby

別の同じタイプの構造体と友達になるには:

#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と書くべきではありません。そうしないと、テンプレートパラメータシャドウエラーが発生します。

7
user6502769

パラメータを指定する必要はありませんので、リファクタリングする場合、失敗点が少なくなります。

     template <typename _KeyT, typename _ValueT> class hash_map_iterator{
       template <typename, typename, int> friend class hash_map;
       ...
3
cpphilosophy