(C++) Iterators com templates

Tenho uma classe :

[code]template <typename Item>
class Chart {

class ChartNode {
public:
	ChartNode *father;
	Item *item;
	list&lt;ChartNode *&gt; subNodes;

	ChartNode(Item *item, list&lt;ChartNode *&gt; subNodes) : item(item), subNodes(subNodes), father(0) {};
} *head;

ChartNode *search(const Item &item);

public:
Chart(Item &head);
virtual ~Chart();

void insert(const Item &son, const Item &father);
void remove(const Item &item);
void remove(const Item &item, const Item &newFather);

};
[/code]

quando tento implementar algum metodo que precise utilizar um iterator como em:

[code]template <typename Item>
void Chart<Item>::remove(const Item &item, const Item &newFather) {
ChartNode *nodeItem = search(item);

if (nodeItem-&gt;subNodes.empty()) return remove(item);
ChartNode *nodeNewFather = search(newFather);
list&lt;ChartNode *&gt; *listCharNodeItem = &nodeItem-&gt;subNodes;

auto it = listCharNodeItem-&gt;begin(); //aqui so consigo um typename valido com auto

}[/code]

como mostrado na linha:

só consigo um nome de iterator valido usando o auto do C++11 pois utilizando algo como:

[color=red]recebo um erro de compilação dizendo que falta um typename no escopo, afinal de contas que erro é esse!!![/color]

Pode postar exatamente a mensagem de erro que você está recebendo?

O que acontece é seguinte.

Como Item é um parâmetro da template, o compilador não tem como saber o que é ::iterator (poderia ser um variável estática de item).

Então, basta usar a palavra chave “typename” antes da declaração para informar ao compilador que isso se trata de um nome de tipo:

O erro até é simpático, ele no fundo está falando para você o que você deveria fazer… heheheh

Poxa! Muito Obrigado, nunca tinha tido um erro como este então fiquei confuso.

Bem-vindo aos templates. :lol:

E olha que esses erro nem tem mais de 40 linhas de comprimento (como acontece muito com templates).

Algumas dicas:
a) Cuidado com as passagens de parâmetros - aqui no seu construtor, por exemplo, você passou um list<ChartNode *> por valor, o que nesse caso parece ser legítimo. Mas tente sempre usar a versão “const” das coisas, caso possível (é o que aparentemente você tentou fazer).
Neste caso em particular, você poderia até ter usado:

            ChartNode(Item *item, const list<ChartNode *>&  subNodes) : item(item), subNodes(subNodes), father(0) {};  

b) Os nomes habituais em inglês não são “father” , “brother” e “son” mas “parent”, “sibling” e “child” (plural “children”). (OK, existe a “motherboard” mas ela não faz parte de uma árvore :slight_smile: )