Page 1 of 1
using a template class inside another template class in C++
Posted: Thu Oct 02, 2008 6:01 pm
by smitty5658
I'm currently writing a linked list template class that uses a node template class. The node template works great but when I try to run the linked list template, my compiler complains that node is not a type even though I included the node header in the linked list header. I was curious if there is a restriction on nesting template classes like this that I wasn't aware of. Thanks in advance.
Re: using a template class inside another template class in C++
Posted: Thu Oct 02, 2008 7:49 pm
by pcmattman
Are you able to post some code? It's far easier to help if we can see what you've written.
Re: using a template class inside another template class in C++
Posted: Thu Oct 02, 2008 8:19 pm
by smitty5658
That's no problem. I appreciate the response.
FYI the node class is called element and the compiler error occurs in the linked_list.template insertion functions saying
'element' is not a type
element.h
Code: Select all
#ifndef _ELEMENT_H
#define _ELEMENT_H
template <class Item>
class element
{
public:
element(Item new_element_data); //constructor
Item get_element_data(); //returns element data
void set_element_data(Item new_element_data); //updates element data
element<Item>* get_previous_element(); //returns a pointer to the previous element in the list
element<Item>* get_next_element(); //returns a pointer to the next pointer in the list
void set_next_element(element<Item>* new_next_element); //updates the pointer to the next element
void set_previous_element(element<Item>* new_prev_element); //updates the pointer to the previous element
private:
Item element_data; //element data
element<Item>* next_element; //pointer to the next element in the list
element<Item>* previous_element; //pointer to the previous element in the list
};
#include "element.template"
#endif
element.template
Code: Select all
template <class Item>
element<Item>::element(Item new_element_data)
{
element_data = new_element_data;
previous_element = NULL;
next_element = NULL;
}
template <class Item>
Item element<Item>::get_element_data()
{
return element_data;
}
template <class Item>
void element<Item>::set_element_data(Item new_element_data)
{
element_data = new_element_data;
}
template <class Item>
element<Item>* element<Item>::get_previous_element()
{
return previous_element;
}
template <class Item>
element<Item>* element<Item>::get_next_element()
{
return next_element;
}
template <class Item>
void element<Item>::set_previous_element(element<Item>* new_previous_element)
{
previous_element = new_previous_element;
if (new_previous_element->get_next_element() != this)
new_previous_element->set_next_element(this);
}
template <class Item>
void element<Item>::set_next_element(element<Item>* new_next_element)
{
next_element = new_next_element;
if (new_next_element->get_previous_element() != this)
new_next_element->set_previous_element(this);
}
linked_list.h
Code: Select all
#ifndef _LINKED_LIST_H
#define _LINKED_LIST_H
#include "element.h"
template <class Item>
class linked_list
{
public:
unsigned list_length(); //returns the number of elements in the list
void delete_element(element<Item>* element_address); //deletes the given element and restores chain of links between elements
element<Item>* find_element_pointer(element<Item>* element_address);
Item return_head_element_data(); //returns the data in the element at the head of the list
Item return_tail_element_data(); //returns the data in the element at the tail of the list
void insert_new_head_element(const Item& new_element_data); //inserts a new head element
void insert_new_element(element<Item>* new_element_position, const Item& new_element_data); //inserts a element in the list
void insert_new_tail_element(const Item& new_element_data); //inserts a new tail element
element<Item>* find_element_data(const Item& data); //returns a pointer to the element whose data matches the parameter
private:
element<Item>* head_element; //pointer to the "head" element
element<Item>* tail_element; //pointer to the "tail" element
};
#include "linked_list.template"
#endif
linked_list.template
Code: Select all
template <class Item>
unsigned linked_list<Item>::list_length()
{
if (head_element == NULL)
return 0;
else
{
element<Item>* current_element = head_element;
int i;
for (i = 1; current_element->get_next_element() != NULL; ++i)
current_element = current_element->get_element_link();
return i;
}
}
template <class Item>
void linked_list<Item>::delete_element(element<Item>* element_address)
{
if (element_address == NULL)
return;
if (element_address->get_next_element() != NULL)
element_address->get_next_element()->set_previous_element(element_address->get_previous_element());
if (element_address->get_previous_element() != NULL)
element_address->get_previous_element()->set_next_element(element_address->get_next_element());
delete element_address;
}
template <class Item>
element<Item>* linked_list<Item>::find_element_pointer(element<Item>* element_address)
{
if (element_address == NULL)
return NULL;
element<Item>* i;
for(i = head_element; i != NULL; i = i->get_next_element())
{
if (i == element_address)
return i;
}
return NULL;
}
template <class Item>
Item linked_list<Item>::return_head_element_data()
{
return head_element->get_element_data();
}
template <class Item>
Item linked_list<Item>::return_tail_element_data()
{
return tail_element->get_element_data();
}
template <class Item>
void linked_list<Item>::insert_new_head_element(const Item& new_element_data)
{
element<Item> e1 = new element(new_element_data);
e1.set_next_element(head_element);
head_element = &e1;
}
template <class Item>
void linked_list<Item>::insert_new_element(element<Item>* previous_element, const Item& new_element_data)
{
if (previous_element == NULL || previous_element == tail_element)
return insert_new_tail_element(new_element_data);
element<Item> e1 = new element(new_element_data);
if (previous_element->get__next_element() != NULL)
{
e1.set_next_element(previous_element->get_next_element());
e1.get_next_element()->set_previous_element(&e1);
}
previous_element->set_element_link(&e1);
}
template <class Item>
void linked_list<Item>::insert_new_tail_element(const Item& new_element_data)
{
element<Item> e1 = new element(new_element_data);
tail_element->set_next_element(&e1);
tail_element = &e1;
}
template <class Item>
element<Item>* linked_list<Item>::find_element_data(const Item& data)
{
element<Item>* i;
for(i = head_element; i != NULL; i = i->get_next_element())
{
if (i->get_element_data() == data)
return i;
}
return NULL;
}
I apologize for the lack of comments in the template files in advance
Re: using a template class inside another template class in C++
Posted: Thu Oct 02, 2008 8:38 pm
by pcmattman
I assume you use G++. Visual C++ 2005 (not the express edition) compiles the code properly - but there's a lot of bugs and mistakes (so I never actually got to a working state). Of course, VC++ allows you to get away with a bit more than G++ does.
Do you mind posting the code which you use to test? It shouldn't be failing until you actually try to use a template anyway, so it'd be nice to see the code you use.
Re: using a template class inside another template class in C++
Posted: Thu Oct 02, 2008 8:54 pm
by smitty5658
BTW I'm using Dev C++
I haven't written an actual testing function for the linked list yet because the template can't pass the syntax checker feature of my compiler. I have been using a blank main function with an include to the linked list header. If you would like, I can post that but I don't think it will be useful.
I'm not sure if this will help but I plan on using the linked list in implementing a stack template in lieu of an array.
Re: using a template class inside another template class in C++
Posted: Thu Oct 02, 2008 10:38 pm
by pcmattman
Would you mind copying and pasting the exact error(s)?
Re: using a template class inside another template class in C++
Posted: Fri Oct 03, 2008 6:27 am
by smitty5658
No problem here's the compiler messages
Code: Select all
3 C:\Users\Jason\Documents\CECS302\New Folder\linked_list.h:23,
from main.cpp In file included from linked_list.h:23,
from main.cpp
C:\Users\Jason\Documents\CECS302\New Folder\linked_list.template In member function `void linked_list<Item>::insert_new_head_element(const Item&)':
57 C:\Users\Jason\Documents\CECS302\New Folder\linked_list.template `element' is not a type
C:\Users\Jason\Documents\CECS302\New Folder\linked_list.template In member function `void linked_list<Item>::insert_new_element(element<Item>*, const Item&)':
67 C:\Users\Jason\Documents\CECS302\New Folder\linked_list.template `element' is not a type
C:\Users\Jason\Documents\CECS302\New Folder\linked_list.template In member function `void linked_list<Item>::insert_new_tail_element(const Item&)':
79 C:\Users\Jason\Documents\CECS302\New Folder\linked_list.template `element' is not a type
C:\Users\Jason\Documents\CECS302\New Folder\Makefile.win [Build Error] n\make.exe: *** [main.o] Error 1
Thanks again for your time
Re: using a template class inside another template class in C++
Posted: Fri Oct 03, 2008 6:49 am
by AJ
Hi,
For the first error in "insert_new_head_element(const Item&)":
Code: Select all
element<Item> e1 = new element(new_element_data);
Shouldn't this be:
Code: Select all
element<Item> e1 = new element<Item>(new_element_data);
?
And it looks like the other messages are in a similar vein...
Cheers,
Adam
Re: using a template class inside another template class in C++
Posted: Fri Oct 03, 2008 7:59 am
by smitty5658
that fixed it
thanks guys