Reputation: 63
I have the following code that doesn't compile on GCC 4.9 as well as GCC 5.1. And I can't seem to figure out why. Sorry if this is a noob question, I am kind of new to C++ templates.
template<class T>class A
{
template<class X>friend class B;
struct C {};
};
template<class X>class B
{
template<class T>friend struct A<T>::C;
};
int main()
{
A<int> a;
B<float> b;
}
When compiled I get the following errors
root@localhost# g++-49 templatefriend.cpp
templatefriend.cpp: In instantiation of âclass B<float>â:
templatefriend.cpp:38:9: required from here
templatefriend.cpp:27:9: error: âstruct A<T>::Câ is private
struct C {};
^
templatefriend.cpp:31:1: error: within this context
{
^
where as this compiles fine if I remove the templates
class A
{
friend class B;
class C{};
};
class B
{
friend class A::C;
};
int main()
{
A a;
B b;
}
Any help is appreciated, or if such a question has already been asked, please share the link.
Upvotes: 3
Views: 393
Reputation: 36882
The warning you get from clang in this case is a bit more helpful:
warning: dependent nested name specifier 'A<X>::' for friend class declaration is not supported
In other words, A::C is a dependent type, so it doesn't work (though I don't off-hand know where in the standard this is described.
What I suspect is that in reality you only want the relationship to be between A<T>
and B<T>
where T
is the same (eg A<int>
and B<int>
but not A<char>
and B<float>
). If that is the case you can accomplish this by using the same template parameter in the friend declaration
template <typename T> class B;
template<class T>
class A {
friend class B<T>; // B of the same templated type is my friend
struct C {};
};
template<class T>
class B {
friend struct A<T>::C; // A::C of the same templated type is my friend
};
The other alternative is to have template <typename> class A;
inside of B
, which would then also make A::C
a friend.
Upvotes: 2