请考虑以下完全正常的代码段:
class A
{
private:
int d;
public:
A(int n){ d = n;}
friend int foo(A a);
};
int foo(A a)
{
return a.d;
}
但是,当我尝试为类使用模板时,我需要转发声明友元函数才能运行,如下所示:
template <typename T>
class B;
template <typename T>
T foof(B<T> a);
template <typename T>
class B
{
private:
T d;
public:
B(T n){ d = n;}
friend T foof<>(B<T> a);
};
template <typename T>
T foof(B<T> a)
{
return a.d;
}
为什么前面的声明在第二个例子中是必要的而不是在第一个例子中?另外,为什么我必须将<>
放入B类中的foof声明中?为什么它不足以在模板内声明?我试图理解这些东西是如何工作的,这样当我需要使用它时,我不必盲目地记住这种代码。
由于
答案 0 :(得分:6)
那是因为
friend int foo(A a);
同时宣布功能和朋友,但是:
friend T foof<>(B<T> a);
是模板实例化的朋友声明。那不一样。实例化不会声明模板功能。
您可以与整个功能模板建立联系,然后不需要转发声明:
template <typename T>
class B
{
private:
T d;
public:
B(T n){ d = n;}
template<class U>
friend U foof(B<U> a);
};
答案 1 :(得分:3)
为什么前面的声明在第二个例子中是必要的而不是在第一个例子中?
因为语法上第二个不是可用于声明函数的形式,但第一个是。
另外,为什么我要把&lt;&gt;在B类内宣告foof?为什么在模板内声明它是不够的呢?
你表示你正在为一个功能模板的专业化提供信息,而不是为一个非模板的功能提供信息,这就是它的意思。您可以拥有类模板的非模板友元函数。