Okay, I’ve got a noob question. It’s been awhile since I coded so I thought I’d start off at the beginning and create a template list and tree. Back in the old days I left the nodes open, but I wanted to keep the data private this time. My first thought was to make the node class a friend of the list. For example:

template <class T>
class node
{
	friend class list;
public:
	node() { prev = NULL; next = NULL; };
	T get() { return this->key; };
private:
	T key;
	static int count;
	node <T> *prev;
	node <T> *next;
};

Gives me a bunch of errors: “class template has already been declared as a non-class template”, “multiple template parameter lists are not allowed”. It looks as though the compiler is ignoring the “friend” part of things and seeing queue as a definition. Yet every online example I’ve found follows this format.

So, okay, there’s no real reason the node needs to be its own class. Instead I make it a nested class within list, which will be the only class that needs to see the node anyway. That works… mostly… Except when the user says “remove node with key of ‘strawberry’” I want the removeNode method to call a findSpecNode(key) method that returns the address of the node. I could do that in the removeNode method but I’d rather farm it out to its own method.

template <class LISTDATA>
listNode<LISTDATA> *list<LISTDATA>::findSpecNode (LISTDATA ToFind)
{
	listNode *tempNode = NULL;
	if (this->start != NULL)
	{
		tempNode = this->start;
		while (tempNode->next != NULL && tempNode->key != ToFind)
			tempNode = tempNode->next;
		if (tempNode->key != ToFind)
			throw exceptions ("Error (list.findSpecNode): Could not find node in list");
	}
	else
	{
		throw exceptions("Error (list.findSpecNode): could not find node, list empty");
	}
	return tempNode;
}

That isn’t working either. I’m getting the following error messages. I’ve looked them up, but I they aren’t relevant. Also, if I make that method void instead of listNode<LISTDATA>* it compiles fine. So I’m guessing the whole problem is the compiler not recognizing a return type of <T>*?

//All errors are from this line:
listNode<LISTDATA> *list<LISTDATA>::findSpecNode (LISTDATA ToFind)

error C2143: syntax error : missing ';' before '<'
eerror C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2988: unrecognizable template declaration/definition
error C2059: syntax error : '<'
error C2065: 'LISTDATA' : undeclared identifier

There’s got to be something I’m not understanding about this whole thing; something I can’t remember or wasn’t taught to begin with. I can do a workaround, put a global cursor in or something, but I guess I got “globals are bad, make everything modular” drilled into my head a bit too much back in school Besides, I’d rather know why than how. Can anyone steer me in the right direction here? Why doesn’t friend work? Why doesn’t return <T>* work?

Oh, C++ using Microsoft Visual Studio 2008. Thank you very muchly.

Recommended Answers

All 7 Replies

Could you attach (using the advanced editor) the files that you are working with so that I can have a poke around?

Is listNode a even template class? I ask because of this contradiction statements :

listNode<LISTDATA>*

vs

listNode *tempNode = NULL

firstPerson: listNode, in that incarnation, is a template class within list which contains prev and next pointers and data of type LISTDATA.

template <class LISTDATA>
	class list
	{
	private:
		template <class LISTDATA>
		class listNode
		{
		public:
			listNode () { prev = NULL; next = NULL; };
			~listNode () { };
			LISTDATA key;
			listNode *prev;
			listNode *next;
		};
		// SO ON AND SO FORTH
	};

As I understand it that is correct for a method header that returns the address of a class which contains <T>, but a declaration inside the method doesn't require that. However, I'm obviously having some problems with syntax there so clearly there's something I'm not understanding.

caged_fire. Ahhh, that's how you attach files. Ha. Done. Some of it's going to be pretty messy, apologies.

The problems all seem to be with your "findSpecNode" function. If you adapt your code to return the index of the node that you are searching for (and not a pointer to a 'non-concrete type') then it seems to compile fine :)

Also the function declaration didn't actually match your implementation. You had declared it as void but you were then implementing it to return a pointer to a listNode. Anyway as I said, if you return the index of the node you are searching for and not a pointer to the node itself, then it seems to be problem solved.

caged_fire: Ha. Yeah, I'd changed the declaration to void to see if it would compile without returning the pointer. Apparently I forgot to change it back. Brain not good right now. Okay, so I'll need to do a workaround for this, or maybe just incorporate findSpecNode into removeNode since that's the only method I use it in. Thanks for the look over.

No problem :) Let me know how you get on. If you need any more help then I'll have a another look at your code and perhaps look into building a complete working solution so that I can post up a bit of code

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.