How do I declare a templated type that refers to itself?
template <class T = Animal> class Animal
{
public:
T getChild ();
}
With this, I get a compiler error concerning a missing type specifier. I tried to forward-declare Animal
, without success.
I am trying to impose a type constraint. A Lion
can only have a Lion
as a child, a Bear
has a Bear
, and so on.
EDIT
I'll post part of the actual class. It is a template for classes that can appear in a linked list:
template <class T = Linked<T> > class Linked
{
private:
T* m_prev;
T* m_next;
}
I want to enforce that the class can only point to object of the same class (or a subclass).
The usual way to do something like a linked list is:
Does this work for you, and if not, what are you trying to accomplish that can't be done this way?
The OP has been answered but I want to chime in because the immediate cause of the problem is not recursion, as others claim. The simplest reason this wouldn't work is that class templates are not types. They are templates. Similarly, function templates are not functions either. So all of this is nonsensical:
Notice that in the
vec1
case,std::list
is not related tostd::vector
. The template is fully defined (assuming header inclusion) at the point of instantiation. It still won't work.Instead, the following works:
Notice that in the vec2 case, it's fine to pass an instantiation of the template itself.
For the record, a toy solution to the toy problem on writing a template that refers to itself, using the proverbial layer of indirection:
Not terribly powerful given the few things that are possible with a template (the
T
parameter insideindirection
). It's of course possible to write arebind
-style metafunction that returns an instantiation ofT
.In this case, you need to specify some type parameter to Animal in your typename definition, or else it would be an "infinite recursion" in the type construction:
You can't create a template class wherein the template type is the class itself. This is a logical recursion that your compiler can't mitigate. Since templates require the compiler to construct the object when a specific typing is encountered ( say Animal ), you have to have a complete definition of the template type. Otherwise, the compiler will recursively try to construct objects. Since your object self-references, this will be an non-terminating recursion.
This use-case seems much more appropriate for inheritance than for templates.
Doing this will let you compile: template class Animal { public: T getPrey (); }
Or, if you really wan't a default argument:
Yet, cheetah must not use itself or Animal as one of its potential template types.