Templates
Apr 18, 2010 at 5:17pm UTC
Hello Everyone!
I am currently trying to use function templates in order to rewrite two linked list functions "appendNode" and "insertNode". However, I don't think that I am quite getting the hang of it and I have alot of errors that I don't know how to fix. Any help with this problem would be much appreciated. Thanks!
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 65 66 67 68 69 70 71 72 73 74 75 76
// This program uses function templates to rewrite the append
// and insert node functions from our linked list notes
// so that they will accept any data type.
#include <iostream>
using namespace std;
template <class T>
struct ListNode {
T value;
struct ListNode *next;
};
ListNode *head = NULL;
void appendNode(T num);
void insertNode (T num);
int main()
{
}
template <class T>
void appendNode(T num)
{
struct ListNode *newNode, *nodePtr = head;
newNode = new ListNode;
if (newNode == NULL) {
cout << "Error allocating memory for new list member!\n" ;
return 1;
}
newNode->value = num;
newNode->next = NULL;
if (head == NULL) {
cout << "List was empty - " << newNode->value;
cout << " is part of list's first node.\n" ;
head = newNode;
}
else {
while (nodePtr->next != NULL)
nodePtr = nodePtr->next;
nodePtr->next = newNode;
}
return 0;
}
template <class T>
void insertNode (T num)
{
struct ListNode *newNode, *nodePtr = head, *prevNodePtr = NULL;
newNode = new ListNode;
if (newNode == NULL) {
cout << "Error allocating memory for new list member!\n" ;
return 1;
}
newNode->value = num;
newNode->next = NULL;
if (head == NULL) {
cout << "List was empty - " << newNode->value;
cout << " is part of list's first node.\n" ;
head = newNode;
}
else {
while ((nodePtr != NULL) && (nodePtr->value < num)) {
prevNodePtr = nodePtr;
nodePtr = nodePtr->next;
}
if (prevNodePtr == NULL)
newNode->next = head; head = newNode;
else
newNode->next = nodePtr; prevNodePtr->next = newNode;
}
return 0;
}
Apr 18, 2010 at 5:50pm UTC
Line 14: 'ListNode' is a template, so you can't define it like that. You need to give it a type to use for 'T'
For example:
ListNode<int > *head = NULL;
. This will compile okay because you give 'int' for T.
Lines 16 and 17: You're using T as a type, but those functions aren't templated so the compiler doesn't know what T is:
1 2 3 4 5
template <class T>
void appendNode(T num);
template <class T>
void insertNode (T num);
This will fix that problem.
Apr 19, 2010 at 12:24pm UTC
As a side note, a typical error is:
1 2 3 4 5
newNode = new ListNode;
if (newNode == NULL) {
cout << "Error allocating memory for new list member!\n" ;
return 1;
}
By default, newNode will never be NULL, so the if check() is completely useless.
new never returns NULL; rather it throws std::bad_alloc if allocation fails. If you
_really_ want to handle out of memory errors yourself, then you have to use
the nothrow version of new:
1 2 3
#include <new>
newNode = new (std::nothrow) ListNode;
Apr 19, 2010 at 2:32pm UTC
@Disch thanks for the help with my errors.
@jsmith thanks for the information.
Apr 19, 2010 at 2:33pm UTC
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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
// This program uses function templates to rewrite the append
// and insert node functions from our linked list notes
// so that they will accept any data type.
#include <iostream>
using namespace std;
template <class T>
struct ListNode {
T value;
struct ListNode *next;
};
ListNode<int > *head = NULL;
template <class T>
void appendNode(T num);
template <class T>
void insertNode (T num);
int main()
{
}
template <class T>
void appendNode(T num)
{
struct ListNode *newNode, *nodePtr = head;
newNode = new ListNode;
if (newNode == NULL) {
cout << "Error allocating memory for new list member!\n" ;
return 1;
}
newNode->value = num;
newNode->next = NULL;
if (head == NULL) {
cout << "List was empty - " << newNode->value;
cout << " is part of list's first node.\n" ;
head = newNode;
}
else {
while (nodePtr->next != NULL)
nodePtr = nodePtr->next;
nodePtr->next = newNode;
}
return 0;
}
template <class T>
void insertNode (T num)
{
struct ListNode *newNode, *nodePtr = head, *prevNodePtr = NULL;
newNode = new ListNode;
if (newNode == NULL) {
cout << "Error allocating memory for new list member!\n" ;
return 1;
}
newNode->value = num;
newNode->next = NULL;
if (head == NULL) {
cout << "List was empty - " << newNode->value;
cout << " is part of list's first node.\n" ;
head = newNode;
}
else {
while ((nodePtr != NULL) && (nodePtr->value < num)) {
prevNodePtr = nodePtr;
nodePtr = nodePtr->next;
}
if (prevNodePtr == NULL)
newNode->next = head; head = newNode;
else
newNode->next = nodePtr; prevNodePtr->next = newNode;
}
return 0;
}
Apr 19, 2010 at 5:48pm UTC
To ohsnap1319 You have marked this thread as solved.
However, I just cannot see the code above (posted at Apr 19, 2010 at 3:33pm) compiling at all.
Apr 19, 2010 at 6:53pm UTC
You also did not take jsmith's advice.
Apr 20, 2010 at 10:09am UTC
Disch is right with the line-14 comment about templates, however I recommend you move the head-variable into the struct (as static) so you can make use of T as template argument. After all, you want your template to work with all kinds of types (that's the whole idea of making it a template, right?)
1 2 3 4 5
template <class T>
struct ListNode {
...
static ListNode<T> *head = NULL;
};
Next for appendNode and insertNode: You have to specify the template parameter to ListNode as well. Everywhere you use "ListNode", that would be "ListNode<T>". ListNode without any <> afterwards is just the name of a template, and not a type.
And jsmith is right! you should think about your null-checking on new. If you don't happen to work with a very ancient compiler, (Like Visual Studio 5.0) it's just useless.
Ciao, Imi.
Topic archived. No new replies allowed.