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 = ...;