模板友元函数的前向声明

Forward declaration of template friend function

考虑以下运行良好的代码片段:

class A
{
private:
    int d;
public:
    A(int n){ d = n;}
    friend int foo(A a);
};

int foo(A a)
{
    return a.d;
}

但是,当我尝试为class使用模板时,我需要将它的友元函数转发声明给运行,如下:

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;
}

为什么第二个例子需要前向声明,而第一个例子不需要?另外,为什么我必须将 <> 放在 class B 内的 foof 声明中?为什么在模板内部声明它还不够?我正在努力理解这些东西是如何工作的,这样我就不用在需要使用的时候盲目地死记硬背这种代码了。

谢谢

那是因为

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);
};

Why is the forward declaration necessary in the second example but not on the first one?

因为在语法上第二种不是可用于声明函数的形式,但第一种是。

Also, why do I have to put <> in the declaration of foof inside class B? Why isn't it enough that it is declared inside of the template?

您表示您正在为函数模板的特化加好友,而不是为非模板的函数加好友,否则这就是它的意思。您可以拥有 class 个模板的非模板友元函数。