Consider the following header file:
template <typename T> struct tNode
{
T Data; //the data contained within this node
list<tNode<T>*> SubNodes; //a list of tNodes pointers under this tNode
tNode(const T& theData)
//PRE: theData is initialized
//POST: this->data == theData and this->SubNodes have an initial capacity
// equal to INIT_CAPACITY, it is set to the head of SubNodes
{
this->Data = theData;
SubNodes(INIT_CAPACITY); //INIT_CAPACITY is 10
}
};
Now consider a line of code from another file:
list<tNode<T>*>::iterator it(); //iterate through the SubNodes
The compiler is giving me this error message: Tree.h:38:17: error: need ‘typename’ before ‘std::list<tNode<T>*>::iterator’ because ‘std::list<tNode<T>*>’ is a dependent scope
I have no idea why the compiler is yelling at me for this.
In list<tNode<T>*>::iterator
, you have a dependant name, that is, a name that depends on a template parameter.
As such, the compiler can't inspect list<tNode<T>*>
(it doesn't have its definition at this point) and so it doesn't know whether list<tNode<T>*>::iterator
is either a static field or a type.
In such a situation, the compiler assumes that it is a field, so in your case it yields a syntax error. To solve the issue, just tell the compiler that it is a type by putting a typename
ahead of the declaration:
typename list<tNode<T>*>::iterator it
Firstly, as other answers already noted, type names nested into dependent types need to be prepended with the typename
keyword.
That keyword is not needed when the template is fully specialized, meaning that list<tnode<int>*>::iterator
does not need typename
, but when the outer class still depends on template parameter T
, typename
must be present.
template <typename T> void foo() {
list<tnode<int>*>::iterator it1; // OK without typename
typename list<tnode<T>*>::iterator it2; // typename necessary
}
Secondly, even with typename
the
typename list<tNode<T>*>::iterator it();
declaration will declare a function, not an iterator. Remove the ()
.
list<tNode<T>*>::iterator
is a dependant name, a type that depends on a template parameter. In order to declare that variable, you need to use the typename
keyword:
typename list<tNode<T>*>::iterator it = ...;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With