Multiple/Chained class templates

closed account (Lv0f92yv)
I am using class templates for a generic doubly linked list... I need to instantiate something like

LinkedList<Node<int>> list; - but get unresolved externals when declaring the template in LinkedList class as

1
2
3
4
template <class T>
LinkedList<T>::LinkedList() {
	...
}


I thought I saw somewhere where you can chain template tags together...

Unless template specialization is how to acheive this...

Thanks.
Don't forget to leave a space between the two closing >. LinkedList<Node<int> >
Are you putting the template function definition separate from the declaration?

Oh, and you need to space the closing template brackets, or the compiler might interpret that as a right shift operator.
LinkedList<Node<int> > list;
closed account (Lv0f92yv)
Are you putting the template function definition separate from the declaration?


No. My linked list class looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
//#include "node.h"

template <class T>
class LinkedList {
public:
	LinkedList();
	~LinkedList();
	Node<T>* head;
	Node<T>* tail;
	int size;

	void add( Node<T>* );
	Node<T>* remove( Node<T>* );
};

template <class T>
LinkedList<T>::LinkedList() {
	head = NULL;
	tail = NULL;
	size = 0;
}

template <class T>
void add(  Node<T> n ) {

	//we begin with empty list
	if ( head == NULL ) {
		head = n;
		tail = n;
		size++;
		return;
	}

	Node<T>* cur = head; //start at the beginning

	while ( cur->next != NULL ) {
		cur = cur->next;
	}

	cur->_next = n;
	n->_prev = cur;
	tail = n; //make the node just added the tail.

	//we added a node
	size++;
}

template <class T>
Node<T>* remove( Node<T>* n ) {
	if ( head == NULL ) {
		cout << "List empty! Can't remove!\n";
		return NULL;
	}
	char* delKey = n->_key;
	Node<T>* cur = head;

	while ( cur->_key != delKey && cur->_next != NULL ) {
		cur = cur->_next;
	}
	cur->_prev->_next = cur->_next;
	cur->_next->_prev = cur->_prev;

	return cur;
}


I am attempgint to instantiate the LinkedList object with type argument Node<int>, since Node is also a templated class.

Put the space in there (thanks for that, didn't even think of right shift opp), and compiler still complains.
Ah, here we go. add() on line 24 and remove() on line 49 are not members of LinkedList, because you didn't give them any scope, as you did with the constructor, so they're just regular global functions.

According to your structure here, the proper declaration of a LinkedList object is LinkedList<T>, not LinkedList<Node<T> >. You're already passing the template parameter to Node inside the class definition, so unless you want your nodes to contain nodes, you only need to pass T.
closed account (Lv0f92yv)
Good catch on the scoping...

I see "error: identifier T is undefined" when instantiating LinkedList<T> list; as such...
I didn't think I needed to say this, but I was using T as a placeholder. You have to replace it with whatever it is you want to use.
Also, it's a good idea to stay away from naming a variable "list" because there is a std::list.
closed account (Lv0f92yv)
Indeed I tried Node and int in place of T (the list is composed of Node objects, so Node would make sense...), no luck. And I will change the var name...

I get

unspecialized class template can't be used as a template argument for template parameter 'T', expected a real type

when using Node in LinkedList<Node> linkedList; declaration.

Edit: Looks like I had made a different mistake in my argument to add that was giving me unrelated (to me) compile errors. I corrected that and am using <int> as the type spec, since LinkedList is using Node<T> in their declarations. It works now, thanks.

(For some reason, passing by value instead of by reference to LinkedList::add caused errors pointing to my declaration of the LinkedList variable...)
Last edited on
add() should take const T &, not Node<T>. It's only annoying to have have to manually construct nodes each time you want to add one to the list. The list should do it automatically.
Also, I just noticed something else in add(). You're iterating from the head of the list to the tail, but the list is doubly-linked. Why not just add to the tail and avoid all those unnecessary iterations?
1. temp=tail
2. tail=new_node
3. tail.prev=temp
4. temp.next=tail
closed account (Lv0f92yv)
Wow, good point.... this is much easier, conceptually.

So instead of manually creating the nodes on creation, just add whatever (value the node will have) to the list directly, and have the list create the node objects... Yea, that makes perfect sense actually. Will make the notation easier to read (not that that's really a problem), but yea.

Thanks... Man I love this forum.
Topic archived. No new replies allowed.