C ++ template typename iterator

Considere el siguiente archivo de encabezado:

template  struct tNode { T Data; //the data contained within this node list<tNode*> 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*>::iterator it(); //iterate through the SubNodes 

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

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

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

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

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

 typename list*>::iterator it 

En primer lugar, como ya se han mencionado otras respuestas, los nombres de tipo nesteds 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*>::iterator typename no necesita typename , pero cuando la clase externa aún depende del parámetro de plantilla T , typename debe estar presente.

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

En segundo lugar, incluso con typename el

 typename list*>::iterator it(); 

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

list*>::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*>::iterator it = ...; 

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::iterator ChildIterator; 

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

 typedef typename std::vector::iterator ChildIterator; 

en lugar.