Search code examples
c++templatesfriend

Forward declaration of template friend function


Consider the following code snippet that works perfectly fine:

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

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

However, when I try to use a template for the class, I need to forward declare the friend function for it to run, as follows:

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

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? I am trying to understand how these things work so that I don't have to blindly memorize this kind of code when I need to use it.

Thanks


Solution

  • That is because

    friend int foo(A a);
    

    is declaration of function and a friend at the same time, but:

    friend T foof<>(B<T> a);
    

    Is friend declaration to template instantiation. That's different. Instantiation doesn't declare template function.


    You could befriend whole function template, and then forward declaration isn't needed:

    template <typename T>
    class B
    {
    private:
        T d;
    public:
        B(T n){ d = n;}
        template<class U>
        friend U foof(B<U> a);
    };