(C++) Iterators com templates

6 respostas
DavidUser
Tenho uma classe :
template <typename Item>
class Chart {

	class ChartNode {
	public:
		ChartNode *father;
		Item *item;
		list<ChartNode *> subNodes;

		ChartNode(Item *item, list<ChartNode *> 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);

};
quando tento implementar algum metodo que precise utilizar um iterator como em:
template <typename Item>
void Chart<Item>::remove(const Item &item, const Item &newFather) {
	ChartNode *nodeItem = search(item);

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

	auto it = listCharNodeItem->begin(); //aqui so consigo um typename valido com auto
}
como mostrado na linha:
auto it = listCharNodeItem->begin(); //aqui so consigo um typename valido com auto
só consigo um nome de iterator valido usando o auto do C++11 pois utilizando algo como:
list<ChartNode *>::iterator it = listCharNodeItem->begin();
[color=red]recebo um erro de compilação dizendo que falta um typename no escopo, afinal de contas que erro é esse!!![/color]

6 Respostas

ViniGodoy

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

DavidUser
ViniGodoy

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

DavidUser

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

ViniGodoy

Bem-vindo aos templates. :lol:

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

E

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: )

Criado 15 de julho de 2012
Ultima resposta 16 de jul. de 2012
Respostas 6
Participantes 3