In other words, why does this compile fine :
template
class A{
public:
void f();
};
class B{
friend void A::f();
};
tem
An explicit instantiation of B<int>
before it is used in A<int>::f()
resolves this problem. I assume GCC tries an implicit instantiation of B<int>
in the definition of A<int>::f()
. But the definition of A<int>::f()
is not finished and GCC 'looses' the friend declaration. It looks like a compiler problem.
template<typename Type>
class A
{
public:
void f();
};
template<typename Type> // B is now a templated class
class B
{
friend void A<Type>::f(); // Friending is done using B templated type
};
template
class B<int>; // <= explicit instantiation, that works
template<>
void A<int>::f()
{
B<int>* var = new B<int>();
}
Specializing template class
member function without specializing whole template class
is special case when you are allowed to specialize non-template
member function, so maybe GCC
is confused, and I don't know the reasons, but somehow you can't declare friendship to specialized non-template
member of template class
. Temporary solution would be to specialize whole class template
for this to work.
//class template A
template<typename Type>
class A{
public:
void f();
};
//class A<int>
template<>
class A<int>{
public:
void f();
};
Then, define A<int>::f
:
For class B:
void A<int>::f(){
B* var = new B();
(void)(var);
}
For template class B
:
void A<int>::f(){
B<int>* var = new B<int>();
(void)(var);
}
But I think Clang
is right here, there should be no problems for such friend declaration. It's probably a bug in GCC
.