我们有两个类模板: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的每一个专业的朋友?
答案 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
的更多信息