8

2つのテンプレートクラスがあるとします。

template<class T>
class baseclass1
{
    template<class> friend class baseclass2;
}

template<class D>
class baseclass2
{
     template<class T> void foo( D& x, T& y)
     {
          ...
     }
}

上記のコードにより、すべてのタイプのbaseclass1が、すべてのタイプのbaseclass2多対多の関係を友好することができます。2つの質問があります。

baseclass1が関数だけをフレンドできるようにするための構文は何ですか

baseclass2<class D>::foo<class T>( D& x, T& y).  

baseclass1そして、関数だけを友だちにするための構文は何ですか

baseclass2<class D>::foo<class T>( D& x, T& y)ここで、Tfromはfrom関数とbaseclass1一致します。Tfoo

編集

テンプレートの特殊化を友だちにすることはできないと主張し続ける人たちへ。このコードは機能します

template<class cake>
class foo
{
    public:
        static void bar(cake x)
        {
            cout << x.x;
        }
};


class pie
{
    public:
        void set( int y){ x = y; }
    private:
        int x;

        friend void foo<pie>::bar(pie x);
};

class muffin
{
    public:
        void set( int y){ x = y; }
    private:
        int x;

    friend void foo<pie>::bar(pie x);
};

int main
{
        pie x;
        x.set(5);
        foo<pie>::bar(x);

        muffin y;
        y.set(5);
        //foo<muffin>::foo(y); //Causes a compilation Error because I only friended the pie specialization
}

マフィンが間違ったfooと友達になり、それでもコンパイルエラーが発生する場所に注意してください。これは、関数とクラスの両方で機能します。私の特定の状況ではこれが不可能であることを完全に受け入れたいと思います(実際にはそのように見えています)理由を理解したいと思います。

4

2 に答える 2

2

のすべての可能な専門分野との友情baseclass2<D>::fooはかなり簡単です:

template<class T> class baseclass1;

template<class D>
class baseclass2{
public:
  template<class T>
  void foo(D&, T&){ baseclass1<T> x; x.priv_foo(); }
};

template<class T>
class baseclass1{
  template<class D>
  template<class U>
  friend void baseclass2<D>::foo(D&, U&);

  void priv_foo(){}
};

template<class T>
class baseclass1{
  template<class D>
  template<class U>
  friend void baseclass2<D>::foo(D&, U&);
};

実例。

baseclass2(存在し、テンプレートであるbaseclass1ことを知っているbaseclass2)と2つのテンプレートの前方宣言。1つはクラス用、もう1つは関数用です。クラステンプレートの関数テンプレートのクラス外定義についても、次のようになります。:)

ただし、具体的に友だちbaseclass2<D>::foo<T>になることはできません。または、正しい構文が見つかりません。

回避策は、アクセスを転送し、パスキーパターンと一緒に使用するグローバル関数である可能性がありますが、まあ、それは混乱です(imho):

template<class D> class baseclass2;

template<class D, class T>
void baseclass2_foo(baseclass2<D>& b, D&, T&);

template<class D, class T>
class baseclass2_foo_key{
  baseclass2_foo_key(){} // private ctor
  friend void baseclass2_foo<>(baseclass2<D>&, D&, T&);
};

template<class T>
class baseclass1{
public: // public access, but only baseclass2_foo can create the key
  template<class D>
  void priv_foo(baseclass2_foo_key<D, T> const&){}
};

template<class D, class T>
void baseclass2_foo(baseclass2<D>&, D&, T&){
  baseclass1<T> x;
  x.priv_foo(baseclass2_foo_key<D, T>());
}

template<class D>
class baseclass2{
public:
  template<class T>
  void foo(D& d, T& t){ baseclass2_foo(*this, d, t); }
};

実例。

于 2012-10-30T15:26:40.850 に答える
0

AFAIKのすべてのインスタンス化をfooフレンドとして指定できますが、特定のインスタンス化は指定できません。

template< class T >
class C1 {
public:
    template< class Q > void foo( T& x, Q& y ) {
    }
};
template< class T >
class C2 {
    template< class Y > 
    template< class Q > friend void C1<Y>::foo( Y&, Q& );
};
于 2012-10-30T15:17:37.170 に答える