关于班级模板的朋友的一些问题

时间:2012-03-13 15:14:15

标签: c++ templates friend

我们有两个类模板:A和B,以及一个函数模板f1()。像这样:

template< class T >
class A{};

template< class T >
class B
{
    friend class A<T>;          /* Expression 1 */
    friend void f1( B<T> &b );  /* Expression 2 */
};

template< class T >
void f1( B<T> &b ) {}

int main()
{
    A< int > a;
    B< int > b;

    f1( b );

    return 0;
}

问题1:表达式1使用参数T对A进行专门化 B与参数T的专业化。但如何使每一个 A的所有专业化朋友的专业化?

问题2:如何在类定义之外定义f1? 像这样的代码会产生错误:

undefined reference to `f1(B<int>&)'

问题3:如何制作所有f1()s(谁可以接收B的所有特化作为参数) B的每一个专业的朋友?

2 个答案:

答案 0 :(得分:3)

问题1:使用

template <typename U> friend class A; 

而不是

friend class A<T>;

问题2:表达式2的作用是声明朋友采用B的正常函数,而不是函数模板的特化。要声明朋友T的特化,你需要使用friend子句来查看f1的声明并添加<>来标记f1是一个特化而不是一个重载的普通函数,所以

template< class T >
class B;
template< class T >
void f1( B<T> &b );
template< class T >
class B
{
    friend void f1<>( B<T> &b );
};

template< class T >
void f1( B<T> &b ) {}

问题3解决方案是两者的混合:

class B;
template< class T >
void f1( B<T> &b );
template< class T >
class B
{
    template <typename U> friend void f1( B<U> &b );
};

答案 1 :(得分:2)

问题1:

你真的想做吗?您希望A<int>访问B<float>吗?通常你没有,但如果你真的想要:

template <typename U>
friend class A;

问题2:

2中的问题是你没有将f1模板的实例化作为朋友,而是你试图创建一个非模板化的自由函数f1,它需要{{1} }} 你的朋友。与特定实例化建立联系的正确语法很麻烦:

B<int>

问题3:

要使template <typename T> class B; template <typename T> void f( B<T>& ); template <typename T> class B { friend void f<T>( B<T>& ); }; 的所有专精都成为朋友(再次,你真的想要这个吗?),你可以采用与类模板相同的方法:

f1

有关所有here

的更多信息