c++ templates iterator typename

C++ template typename iterator



templates (4)

Considere el siguiente archivo de encabezado:

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 } };

Ahora considere una línea de código de otro archivo:

list<tNode<T>*>::iterator it(); //iterate through the SubNodes

El compilador me está dando este mensaje de error: Tree.h:38:17: error: need ''typename'' before ''std::list<tNode<T>*>::iterator'' because ''std::list<tNode<T>*>'' is a dependent scope

No tengo idea de por qué el compilador me grita por esto.


En list<tNode<T>*>::iterator , tiene un nombre dependiente , es decir, un nombre que depende de un parámetro de plantilla.

Como tal, el compilador no puede inspeccionar list<tNode<T>*> (no tiene su definición en este punto) y por lo tanto no sabe si list<tNode<T>*>::iterator es cualquiera un campo estático o un tipo.

En tal situación, el compilador asume que es un campo, por lo que en su caso produce un error de sintaxis. Para resolver el problema, simplemente dile al compilador que es un tipo poniendo un typename antes de la declaración:

typename list<tNode<T>*>::iterator it


En primer lugar, como ya se han mencionado otras respuestas, los nombres de tipo anidados en tipos dependientes deben ir precedidos de la palabra clave typename .

Esa palabra clave no es necesaria cuando la plantilla está completamente especializada, lo que significa que la list<tnode<int>*>::iterator typename no necesita typename , pero cuando la clase externa aún depende del parámetro de plantilla T , typename debe estar presente.

template <typename T> void foo() { list<tnode<int>*>::iterator it1; // OK without typename typename list<tnode<T>*>::iterator it2; // typename necessary }

En segundo lugar, incluso con typename el

typename list<tNode<T>*>::iterator it();

declaración declarará una función, no un iterador. Eliminar el () .


Más información sobre las respuestas anteriores se proporciona aquí

Una descripción de la palabra clave typename de C ++

Tuve un problema diferente pero similar en el sentido de que quería escribir un iterador para nodos secundarios con:

typedef std::vector<NodeType*>::iterator ChildIterator;

que me dio el mismo error de compilación. Con las sugerencias aquí y la ayuda del enlace de arriba, la solución a mi problema es usar

typedef typename std::vector<NodeType*>::iterator ChildIterator;

en lugar.


list<tNode<T>*>::iterator es un nombre dependiente, un tipo que depende de un parámetro de plantilla. Para declarar esa variable, debe usar la palabra clave typename :

typename list<tNode<T>*>::iterator it = ...;