问题
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
回答1:
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);
};
回答2:
Why is the forward declaration necessary in the second example but not on the first one?
Because syntactically the second isn't a form that can be used to declare a function, but the first one is.
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?
You're indicating that you're friending a specialization of a function template, as opposed to friending a function that is NOT a template, which is what it would mean otherwise. You can have non-template friend functions of class templates.
来源:https://stackoverflow.com/questions/39678663/forward-declaration-of-template-friend-function