模板朋友语法

时间:2012-10-30 14:52:37

标签: c++ templates

假设我有两个模板类。

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建立友好关系,这是一种多对多的关系。我有两个问题,

允许baseclass1只与函数

相关的语法是什么
baseclass2<class D>::foo<class T>( D& x, T& y).  

并且,允许baseclass1只是函数

的语法是什么

baseclass2<class D>::foo<class T>( D& x, T& y)来自T的{​​{1}}与来自函数baseclass1的{​​{1}}相匹配。

修改

对于那些一直声称你不能成为模板专业化的朋友。此代码有效

T

即使注意松饼朋友错误的foo,仍然会导致编译错误。这适用于函数和类。我完全愿意接受这在我的具体情况下是不可能的(它实际上看起来越来越多)我只是想明白为什么。

2 个答案:

答案 0 :(得分: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&);
};

Live example.

baseclass2的前向声明(所以baseclass1知道baseclass2存在并且是模板)和两个模板,一个用于类,一个用于函数。对于类模板的函数模板的类外定义,它看起来也是如此。 :)

然而,特别是与baseclass2<D>::foo<T>交朋友是不可能的,或者我找不到 正确的语法。

解决方法可能是一些全局函数,可以转发访问权限并与passkey pattern一起转发,但是,这很糟糕(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); }
};

Live example.

答案 1 :(得分: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& );
};