Reputation: 67254
I have a class, say A
template <typename T> class A
{
} ;
and a class derived from A<T>
, (retaining type genericity)
template <typename T> class B : public A<T>
{
} ;
A situation has arisen where i need to instantiate a B<T>
inside a method declared in A<T>
. Uh oh.
template <typename T> class A
{
void go()
{
B<T> * newB = new B<T>() ; // oh boy, not working..
}
} ;
What should I do and how do I work around this?
Upvotes: 1
Views: 76
Reputation: 437424
You can forward-declare the class template A
before inheriting from it -- just be sure to follow the definition of class B
with the definition of the class A
template in the same header:
template <typename T> class A;
template <typename T> class B : public A<T> {};
template <typename T> class A
{
void go()
{
B<T> * newB = new B<T>();
}
};
Upvotes: 1
Reputation: 67254
Another way to do this is write a global function that each of the template
classes declare friend
void go( A<T> *a )
{
// Can now make a B<T>
B<T> *b = new B<T>() ;
// access b's and a's privates if this function
// is friend to A<T> and B<T>
}
Upvotes: 0
Reputation: 153840
You need to break the cyclic dependency between the two classes. Trivial in this case: just define your go()
function out of line:
template <typename T> class A
{
public:
void go();
} ;
template <typename T> class B : public A<T>
{
} ;
template <typename T>
void A<T>::go()
{
B<T> * newB = new B<T>() ;
}
I prefer out of line definitions, even when inlining functions, anyway because it avoids cluttering the interface with unnecessary detail. I also prefer to not have cyclic dependencies (certainly not between base and derived) but it can't always be avoided.
Upvotes: 2