关于类模板的朋友的一些问题

Some problems about class template's friend

本文关键字:问题 朋友 于类模      更新时间:2023-10-16

我们有两个类模板: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使A与自变量T的专业化成为朋友关于B与论点T的专业化。但是如何使A的专业化所有的朋友的专业化的B?

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

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

问题3:如何使所有的f1()s(谁可以将B的所有专业化作为参数)B各专业的朋友?

问题1:使用

template <typename U> friend class A; 

而不是

friend class A<T>;

问题2:表达式2所做的是将friend声明为一个取B的普通函数,而不是函数模板的特殊化。要声明friend为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:

你真的想这么做吗?是否希望A<int>访问B<float>?通常你不会,但如果你真的想要:

template <typename U>
friend class A;

问题2:

2中的问题是,您并没有将f1模板的实例化作为朋友,而是试图将B<int>作为朋友的非模板自由函数f1。与特定实例化交朋友的正确语法很麻烦:

template <typename T> class B;
template <typename T> void f( B<T>& );
template <typename T>
class B {
   friend void f<T>( B<T>& );
};

问题3:

为了让f1的所有专业化成为朋友(再说一遍,你真的想要这个吗?),你可以使用与类模板相同的方法:

template <typename U>
friend void f1( B<U>& );

更多关于这里的