c++ convert existing code to template

Zenoture
Zenoture used Ask the Experts™
on
So I have this existing sorted, circular, 2-way linked list, which I need to now convert to a template so it can handle multiple data types, instead of just int like it does now. I've searched online and tried examples I found but could not get past the errors. My first objective is to set the header up correctly, then move on the implementation file. I'll post both codes below.
// **Header File**
#ifndef LLSORTED_H
#define LLSORTED_H

class llSorted
{
private:
	template <class itemType>struct node;
	struct node
	{
		itemType data;
		node* next;
		node* prev;
	};
	node<itemType> *head, *tail, *cur;
	int MAX_SIZE;
	int length;
	int temp;
	int index;
	int value;
	int cmd;
	bool found;
	bool inserted;

public:
	llSorted();
	bool isFull();
	bool isEmpty();
	void init();
	void printList();
	void InsertItem();
	void RetrieveItem();
	void DeleteItem();
	void getLength();
	void usrVal(int);
	void validation();
	int exit();

};

#endif

Open in new window

 
// ** Implementation File

#include "stdafx.h"

llSorted::llSorted()
{
	srand(time(0));

	head = NULL;
	tail = NULL;
	cur = NULL;
	index = 0;
	MAX_SIZE = 11;
	length = rand() % 10 + 1;
	cmd = 0;
	for (int i = 0; i < length; i++)
	{
		if (head == NULL)
		{
			head = new node;
			head->data = rand() % 101;
			head->next = new node;
			head->prev = NULL;
			cur = head->next;
			cur->prev = head;
		}
		else
		{
			cur->data = rand() % 101;
			cur->next = new node;
			cur->next->prev = cur;
			cur = cur->next;
		}
	}
	tail = cur;
	tail->next = head;
	head->prev = tail;

	// sort the list
	if (head != NULL)
	{
		cur = head;
		for (int i = 0; i < length; i++)
		{
			for (int j = 0; j < length; j++)
			{
				if (cur->next != tail)
				{
					if (cur->data > cur->next->data)
					{
						temp = cur->data;
						cur->data = cur->next->data;
						cur->next->data = temp;
					}
				}
				cur = cur->next;
			}
		}
	}
}

void llSorted::init()
{
	printList();
	cout << "\nAvailable Commands:\n  1. Insert Item\n  2. Retrieve Item\n  3. Delete Item\n  4. List Details\n  9. Select Different Implementation\n  0. Exit\n\nCommand: ";
	while(!(cin >> cmd))
	{
		cout << "Please enter only the number associated with the command\nCommand: ";
		cin.clear();
		cin.ignore(1000, 10);
	}

	switch (cmd)
	{
	case 1:
		InsertItem();
		break;
	case 2:
		RetrieveItem();
		break;
	case 3:
		DeleteItem();
		break;
	case 4:
		getLength();
		break;
	case 9:
		init();
		break;
	case 0:
		exit();
		break;
	default:
		validation();
		break;
	}
}

void llSorted::printList()
{
	cout << "List: ";
	// memory issue if list is empty
	if (!(isEmpty()))
	{
		cur = head;
		while (cur != tail)
		{
			cout << cur->data;
			if (cur->next != tail)
				cout << ", ";
			cur = cur->next;
		}
	}
}

bool llSorted::isFull()
{
	return (length == MAX_SIZE);
}

bool llSorted::isEmpty()
{
	return (length == 0);
}

void llSorted::InsertItem()
{
	// Check to see if the list is full
	if(isFull())
	{
		cout << "List is Full!\n" << endl;
		init();
	}
	// List is not full, ask user for value and insert sorted
	else
	{
		usrVal(0);
		// if list is empty, just insert it right after head
		if (isEmpty())
		{
			length++;
			cur->data = value;
			cur->next = NULL;
			tail = cur->next;
			cout << endl;
			init();
		}
		else
		{
			// Traverse the list til next is > the value
			cur = head->next;
			inserted = false;
			while (cur != NULL)
			{
				if (value > cur->data)
				{
					cur = cur->next;
				}
				else
				{
					cur = new node;
					cur->data = value;
					inserted = true;
					length++;
					break;
				}
			}
			if (!inserted)
			{
				cur = new node;
				cur->data = value;
				cur->next = NULL;
				tail = cur->next;
				length++;
			}
			cout << endl;
			init();
		}
	}
}

void llSorted::RetrieveItem()
{
	// Check to see if the list is empty
	if(isEmpty())
	{
		cout << "List is empty!\n" << endl;
		init();
	}
	// List is not empty, ask user for value to find
	else
	{
		usrVal(1);
		// Traverse the list until tail is hit
		cur = head;
		index = 0;
		while (cur != tail)
		{
			if (cur->data == value)
			{
				found++;
				cout << "  Found! Properties of '" << cur->data << "':" << endl;
				cout << "  Address:\t\t\t" << &cur->data << endl;
				cout << "  Index:\t\t\t" << index << endl;
				if (cur->next != tail)
					cout << "  Next Address & Value:\t\t" << &cur->next << " = " << cur->next->data << endl;
				cur = cur->next;
			}
			else
				cur = cur->next;
			index++;
		}
		if(!found)
			cout << "Value does not exist!\n";
		cout << endl;
		init();
	}
}

void llSorted::DeleteItem()
{
	// Check if list is empty
	if (isEmpty())
	{
		cout << "List is empty!" << endl;
		init();
	}
	// List is not empty, ask user for value and "delete" item
	else
	{
		usrVal(2);
		// traverse the list until you find the value
		cur = head;
		while(cur->next != tail)
		{
			// check if cur->next contains the value
			if(cur->next->data == value)
			{
				found++;
				length--;
				cur->next = cur->next->next;
			}
			else
				cur = cur->next;
		}
		if(!(found))
			cout << "Value does not exist!\n" << endl;
		cout << endl;
		init();
	}
}

void llSorted::getLength()
{
	// offset by -1 due to NULL head
	cout << "Maximum number of items list can hold:\t" << MAX_SIZE - 1 << endl;
	cout << "Currently stored items:\t\t\t" << length - 1 << endl;
	cout << "Last selected index:\t\t\t";
	if (index == 0)
		cout << "None" << endl;
	else
		cout << index - 1 << endl;
	cout << endl;
	init();
}

void llSorted::usrVal(int val)
{
	cout << "What integer would you like to ";
	if (val == 0)
		cout << "insert? ";
	else if (val == 1)
		cout << "retrieve? ";
	else
		cout << "delete? ";
	while (!(cin >> value))
	{
		cout << "Please enter only integer digits: ";
		cin.clear();
		cin.ignore(1000, 10);
	}
	// reset found to 0
	found = 0;
}

void llSorted::validation()
{
	cout << "Invalid Command. Please try again.\n" << endl;
	init();
}

int llSorted::exit()
{
	cout << "Good bye.";
	return 0;
}

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
One approach is to templatize the llSorted class rather than just the struct node.

Author

Commented:
Tried that and it gave me 50 errors.

Would it still be:
llSorted::llSorted()

Or would it change to:
itemType<int>llSorted::llSorted()?

Also, even if I change the entire class to a template, how does that change the int data in struct?
>> even if I change the entire class to a template, how does that change the int data in struct?You refer to "int" data. But your type for data in the struct is "itemType", which would already be covered by templatizing the entire llSorted class. So, you wouldn't have to use the keyword "template" inside the class llSorted, since  "itemType" is already specified in the template usage.>> Or would it change to: itemTypellSorted::llSorted()?The constructor and exit would be:
template <class itemType>
llSorted<itemType>::llSorted()

template <class itemType>
int llSorted<itemType>::exit()

Open in new window

Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

You should merge the two files into just one .h file.

Author

Commented:
>>You should merge the two files into just one .h file.

Not allowed to. Specifications require 3 files, header, driver and implementation
You could put the implementation in a .cpp file (that you will not compile separately), and then just include this .cpp file after the class template definition in the .h file.
When your driver instantiates a template class that is referenced via the .h file, then the compiler is trying to generate from this generic code specific code for your specific data type.Here is another explanation:    http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12

Author

Commented:
OK, so I ran into the linking issue (as expected) but your recommendation as stated above and in the link don't really make sense to me. Maybe even smaller baby steps are needed for me to understand what's going on and how to fix it lol

Author

Commented:
Updated Code:

// stdafx.h

#include "llSorted.h"

#include <iostream>
#include <cstdlib>
#include <ctime>

using namespace std;

// driver file

#include "stdafx.h"

template <class itemType>
int main()
{
	llSorted<itemType> templatize;
	
	templatize.init();
}


// header file

#ifndef LLSORTED_H
#define LLSORTED_H

template <class itemType>
class llSorted
{
private:
	struct node
	{
		itemType data;
		node* next;
		node* prev;
	};
	node *head, *tail, *cur;
	int MAX_SIZE;
	int length;
	int temp;
	int index;
	int value;
	int cmd;
	bool found;
	bool inserted;

public:
	llSorted();
	bool isFull();
	bool isEmpty();
	void init();
	void printList();
	void InsertItem();
	void RetrieveItem();
	void DeleteItem();
	void getLength();
	void usrVal(int);
	void validation();
	int exit();

};

#endif

// imp file

#include "stdafx.h"

template <class itemType>
llSorted<itemType>::llSorted()
{
	srand(time(0));

	head = NULL;
	tail = NULL;
	cur = NULL;
	index = 0;
	MAX_SIZE = 11;
	length = rand() % 10 + 1;
	cmd = 0;
	for (int i = 0; i < length; i++)
	{
		if (head == NULL)
		{
			head = new node;
			head->data = rand() % 101;
			head->next = new node;
			head->prev = NULL;
			cur = head->next;
			cur->prev = head;
		}
		else
		{
			cur->data = rand() % 101;
			cur->next = new node;
			cur->next->prev = cur;
			cur = cur->next;
		}
	}
	tail = cur;
	tail->next = head;
	head->prev = tail;

	// sort the list
	if (head != NULL)
	{
		cur = head;
		for (int i = 0; i < length; i++)
		{
			for (int j = 0; j < length; j++)
			{
				if (cur->next != tail)
				{
					if (cur->data > cur->next->data)
					{
						temp = cur->data;
						cur->data = cur->next->data;
						cur->next->data = temp;
					}
				}
				cur = cur->next;
			}
		}
	}
}

template <class itemType>
void llSorted<itemType>::init()
{
	printList();
	cout << "\nAvailable Commands:\n  1. Insert Item\n  2. Retrieve Item\n  3. Delete Item\n  4. List Details\n  9. Select Different Implementation\n  0. Exit\n\nCommand: ";
	while(!(cin >> cmd))
	{
		cout << "Please enter only the number associated with the command\nCommand: ";
		cin.clear();
		cin.ignore(1000, 10);
	}

	switch (cmd)
	{
	case 1:
		InsertItem();
		break;
	case 2:
		RetrieveItem();
		break;
	case 3:
		DeleteItem();
		break;
	case 4:
		getLength();
		break;
	case 9:
		init();
		break;
	case 0:
		exit();
		break;
	default:
		validation();
		break;
	}
}

template <class itemType>
void llSorted<itemType>::printList()
{
	cout << "List: ";
	// memory issue if list is empty
	if (!(isEmpty()))
	{
		cur = head;
		while (cur != tail)
		{
			cout << cur->data;
			if (cur->next != tail)
				cout << ", ";
			cur = cur->next;
		}
	}
}

template <class itemType>
bool llSorted<itemType>::isFull()
{
	return (length == MAX_SIZE);
}

template <class itemType>
bool llSorted<itemType>::isEmpty()
{
	return (length == 0);
}

template <class itemType>
void llSorted<itemType>::InsertItem()
{
	// Check to see if the list is full
	if(isFull())
	{
		cout << "List is Full!\n" << endl;
		init();
	}
	// List is not full, ask user for value and insert sorted
	else
	{
		usrVal(0);
		// if list is empty, just insert it right after head
		if (isEmpty())
		{
			length++;
			cur->data = value;
			cur->next = NULL;
			tail = cur->next;
			cout << endl;
			init();
		}
		else
		{
			// Traverse the list til next is > the value
			cur = head->next;
			inserted = false;
			while (cur != NULL)
			{
				if (value > cur->data)
				{
					cur = cur->next;
				}
				else
				{
					cur = new node;
					cur->data = value;
					inserted = true;
					length++;
					break;
				}
			}
			if (!inserted)
			{
				cur = new node;
				cur->data = value;
				cur->next = NULL;
				tail = cur->next;
				length++;
			}
			cout << endl;
			init();
		}
	}
}

template <class itemType>
void llSorted<itemType>::RetrieveItem()
{
	// Check to see if the list is empty
	if(isEmpty())
	{
		cout << "List is empty!\n" << endl;
		init();
	}
	// List is not empty, ask user for value to find
	else
	{
		usrVal(1);
		// Traverse the list until tail is hit
		cur = head;
		index = 0;
		while (cur != tail)
		{
			if (cur->data == value)
			{
				found++;
				cout << "  Found! Properties of '" << cur->data << "':" << endl;
				cout << "  Address:\t\t\t" << &cur->data << endl;
				cout << "  Index:\t\t\t" << index << endl;
				if (cur->next != tail)
					cout << "  Next Address & Value:\t\t" << &cur->next << " = " << cur->next->data << endl;
				cur = cur->next;
			}
			else
				cur = cur->next;
			index++;
		}
		if(!found)
			cout << "Value does not exist!\n";
		cout << endl;
		init();
	}
}

template <class itemType>
void llSorted<itemType>::DeleteItem()
{
	// Check if list is empty
	if (isEmpty())
	{
		cout << "List is empty!" << endl;
		init();
	}
	// List is not empty, ask user for value and "delete" item
	else
	{
		usrVal(2);
		// traverse the list until you find the value
		cur = head;
		while(cur->next != tail)
		{
			// check if cur->next contains the value
			if(cur->next->data == value)
			{
				found++;
				length--;
				cur->next = cur->next->next;
			}
			else
				cur = cur->next;
		}
		if(!(found))
			cout << "Value does not exist!\n" << endl;
		cout << endl;
		init();
	}
}

template <class itemType>
void llSorted<itemType>::getLength()
{
	// offset by -1 due to NULL head
	cout << "Maximum number of items list can hold:\t" << MAX_SIZE - 1 << endl;
	cout << "Currently stored items:\t\t\t" << length - 1 << endl;
	cout << "Last selected index:\t\t\t";
	if (index == 0)
		cout << "None" << endl;
	else
		cout << index - 1 << endl;
	cout << endl;
	init();
}

template <class itemType>
void llSorted<itemType>::usrVal(int val)
{
	cout << "What integer would you like to ";
	if (val == 0)
		cout << "insert? ";
	else if (val == 1)
		cout << "retrieve? ";
	else
		cout << "delete? ";
	while (!(cin >> value))
	{
		cout << "Please enter only integer digits: ";
		cin.clear();
		cin.ignore(1000, 10);
	}
	// reset found to 0
	found = 0;
}

template <class itemType>
void llSorted<itemType>::validation()
{
	cout << "Invalid Command. Please try again.\n" << endl;
	init();
}

template <class itemType>
int llSorted<itemType>::exit()
{
	cout << "Good bye.";
	return 0;
}

Open in new window

Author

Commented:
Link error:

1>------ Build started: Project: Templetized sorted 2-way circular linked list, Configuration: Debug Win32 ------
1>  stdafx.cpp
1>  llSorted.cpp
1>  Lab7.cpp
1>  Generating Code...
1>MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
1>F:\Templetized sorted 2-way circular linked list\Debug\Templetized sorted 2-way circular linked list.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Open in new window

Back for a moment, and will check back in 1 hour. A quick scan shows one thing for sure that should be changed.

Line 15: template <class itemType>
You do not want to templatize the main() entry point function.
Advise removing this line and reporting further problems.

Author

Commented:
Line 15 removed and the following compiling error occurred:
1>------ Build started: Project: Templetized sorted 2-way circular linked list, Configuration: Debug Win32 ------
1>  Lab7.cpp
1>f:\comsc-210 labs\7\templetized sorted 2-way circular linked list\lab7.cpp(22): error C2065: 'itemType' : undeclared identifier
1>f:\comsc-210 labs\7\templetized sorted 2-way circular linked list\lab7.cpp(22): error C2133: 'templatize' : unknown size
1>f:\comsc-210 labs\7\templetized sorted 2-way circular linked list\lab7.cpp(22): error C2512: 'llSorted' : no appropriate default constructor available
1>f:\comsc-210 labs\7\templetized sorted 2-way circular linked list\lab7.cpp(24): error C2662: 'llSorted<itemType>::init' : cannot convert 'this' pointer from 'llSorted' to 'llSorted<itemType> &'
1>          Reason: cannot convert from 'llSorted' to 'llSorted<itemType>'
1>          Conversion requires a second user-defined-conversion operator or constructor
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Open in new window

In line 18: llSorted<itemType> templatize;
>> 'itemType' : undeclared identifier
      you need to change the itemType to your desired type; for example:
 llSorted<int> list_int;
 llSorted<double> list_double;

I noticed:
    temp = cur->data;
Here there is a type mismatch which you should correct.

Since you are including the template implementation into the header, then after you get it to compile, you probably should remove the "using namespace std;" and add "std::" where needed.
Including the template implementation .cpp file in the header was one of the methods to resolve a build error. In this case the .cpp file would not include the .h file (since it is already part of the .h file).If you look at    http://www.parashift.com/c++-faq-lite/templates.html#faq-35.15then you may prefer an alternative approach.Instead of the template implementation .cpp file being included in the .h file, it is a separately compilable unit. In this case, you need to include the .h file in it. The trick is to force all the desired classes to be created by the compiler in this .cpp file. Below are two LOCs to include in the .cpp file that correspond to the two llSorted objects (list_int and list_double). With this approach, you would need to update the .cpp file to handle any new data type for the list.
template class llSorted<int>;
template class llSorted<double>;

Open in new window

Author

Commented:
Not abandoning the question, W7 machine decided to take a dump on me this morning, been trying to fix it ever since. Will post when I'm ready to continue

Author

Commented:
>>In line 18: llSorted<itemType> templatize;
>>>> 'itemType' : undeclared identifier
>>      you need to change the itemType to your desired type; for example:
>> llSorted<int> list_int;
>> llSorted<double> list_double;

changed itemType to int, on line 18, follow errors were generated
1>------ Build started: Project: Templetized sorted 2-way circular linked list, Configuration: Debug Win32 ------
1>  stdafx.cpp
1>  Lab7.cpp
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(6): warning C4244: 'argument' : conversion from 'time_t' to 'unsigned int', possible loss of data
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(5) : while compiling class template member function 'llSorted<itemType>::llSorted(void)'
1>          with
1>          [
1>              itemType=int
1>          ]
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\lab7.cpp(22) : see reference to class template instantiation 'llSorted<itemType>' being compiled
1>          with
1>          [
1>              itemType=int
1>          ]
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(8): error C2065: 'NULL' : undeclared identifier
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(9): error C2065: 'NULL' : undeclared identifier
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(10): error C2065: 'NULL' : undeclared identifier
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(17): error C2065: 'NULL' : undeclared identifier
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(22): error C2065: 'NULL' : undeclared identifier
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(39): error C2065: 'NULL' : undeclared identifier
1>  llSorted.cpp
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(59): error C2995: 'llSorted<itemType>::llSorted(void)' : function template has already been defined
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.h(25) : see declaration of 'llSorted<itemType>::llSorted'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(97): error C2995: 'void llSorted<itemType>::init(void)' : function template has already been defined
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.h(28) : see declaration of 'llSorted<itemType>::init'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(115): error C2995: 'void llSorted<itemType>::printList(void)' : function template has already been defined
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.h(29) : see declaration of 'llSorted<itemType>::printList'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(121): error C2995: 'bool llSorted<itemType>::isFull(void)' : function template has already been defined
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.h(26) : see declaration of 'llSorted<itemType>::isFull'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(127): error C2995: 'bool llSorted<itemType>::isEmpty(void)' : function template has already been defined
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.h(27) : see declaration of 'llSorted<itemType>::isEmpty'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(184): error C2995: 'void llSorted<itemType>::InsertItem(void)' : function template has already been defined
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.h(30) : see declaration of 'llSorted<itemType>::InsertItem'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(223): error C2995: 'void llSorted<itemType>::RetrieveItem(void)' : function template has already been defined
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.h(31) : see declaration of 'llSorted<itemType>::RetrieveItem'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(257): error C2995: 'void llSorted<itemType>::DeleteItem(void)' : function template has already been defined
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.h(32) : see declaration of 'llSorted<itemType>::DeleteItem'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(272): error C2995: 'void llSorted<itemType>::getLength(void)' : function template has already been defined
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.h(33) : see declaration of 'llSorted<itemType>::getLength'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(292): error C2995: 'void llSorted<itemType>::usrVal(int)' : function template has already been defined
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.h(34) : see declaration of 'llSorted<itemType>::usrVal'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(299): error C2995: 'void llSorted<itemType>::validation(void)' : function template has already been defined
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.h(35) : see declaration of 'llSorted<itemType>::validation'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(306): error C2995: 'int llSorted<itemType>::exit(void)' : function template has already been defined
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.h(36) : see declaration of 'llSorted<itemType>::exit'
1>  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Open in new window

Author

Commented:
>>I noticed:
>>    temp = cur->data;
>>Here there is a type mismatch which you should correct.
>>
>>Since you are including the template implementation into the header, then after you get it to compile, >>you probably should remove the "using namespace std;" and add "std::" where needed.

Changed int temp to itemType temp in header file.

As for namespace std, why do I have to remove it? I don't see any errors or warnings that state it's not improper usage, not have I read anywhere that using template and namespace std is bad. I understand what you are asking me to do, but I want to know why I'm doing it so I learn not to do that in the future.

Author

Commented:
>>Including the template implementation .cpp file in the header was one of the methods to resolve a >>build error. In this case the .cpp file would not include the .h file (since it is already part of the .h file).
>>
>>If you look at    http://www.parashift.com/c++-faq-lite/templates.html#faq-35.15
>>then you may prefer an alternative approach.
>>
>>Instead of the template implementation .cpp file being included in the .h file, it is a separately >>compilable unit. In this case, you need to include the .h file in it. The trick is to force all the desired >>classes to be created by the compiler in this .cpp file. Below are two LOCs to include in the .cpp file >>that correspond to the two llSorted objects (list_int and list_double). With this approach, you would >>need to update the .cpp file to handle any new data type for the list.

Ok, but when I tried this approach, the compiler spat out the same errors I have been posting above, saying a template was already defined or declared and cannot be redefined or re-declared, which is why all of this is confusing to me

Author

Commented:
Update:

tried tried the syntax you put in your last post, generated a new set of errors (less, which is a good thing)

Errors:
1>------ Build started: Project: Templetized sorted 2-way circular linked list, Configuration: Debug Win32 ------
1>  stdafx.cpp
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.h(17): error C2182: 'temp' : illegal use of type 'void'
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(3) : see reference to class template instantiation 'llSorted<itemType>' being compiled
1>          with
1>          [
1>              itemType=void
1>          ]
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.h(10): error C2182: 'data' : illegal use of type 'void'
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(3) : see reference to class template instantiation 'llSorted<itemType>::node' being compiled
1>          with
1>          [
1>              itemType=void
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

#include "stdafx.h"

template class llSorted<void>;
template <class itemType>
llSorted<itemType>::llSorted()
{
	srand(time(0));

	head = NULL;
	tail = NULL;
	cur = NULL;
	index = 0;
	MAX_SIZE = 11;
	length = rand() % 10 + 1;
	cmd = 0;
	for (int i = 0; i < length; i++)
	{
		if (head == NULL)
		{
			head = new node;
			head->data = rand() % 101;
			head->next = new node;
			head->prev = NULL;
			cur = head->next;
			cur->prev = head;
		}
		else
		{
			cur->data = rand() % 101;
			cur->next = new node;
			cur->next->prev = cur;
			cur = cur->next;
		}
	}
	tail = cur;
	tail->next = head;
	head->prev = tail;

	// sort the list
	if (head != NULL)
	{
		cur = head;
		for (int i = 0; i < length; i++)
		{
			for (int j = 0; j < length; j++)
			{
				if (cur->next != tail)
				{
					if (cur->data > cur->next->data)
					{
						temp = cur->data;
						cur->data = cur->next->data;
						cur->next->data = temp;
					}
				}
				cur = cur->next;
			}
		}
	}
}

template <class itemType>
void llSorted<itemType>::init()
{
	printList();
	cout << "\nAvailable Commands:\n  1. Insert Item\n  2. Retrieve Item\n  3. Delete Item\n  4. List Details\n  9. Select Different Implementation\n  0. Exit\n\nCommand: ";
	while(!(cin >> cmd))
	{
		cout << "Please enter only the number associated with the command\nCommand: ";
		cin.clear();
		cin.ignore(1000, 10);
	}

	switch (cmd)
	{
	case 1:
		InsertItem();
		break;
	case 2:
		RetrieveItem();
		break;
	case 3:
		DeleteItem();
		break;
	case 4:
		getLength();
		break;
	case 9:
		init();
		break;
	case 0:
		exit();
		break;
	default:
		validation();
		break;
	}
}

template <class itemType>
void llSorted<itemType>::printList()
{
	cout << "List: ";
	// memory issue if list is empty
	if (!(isEmpty()))
	{
		cur = head;
		while (cur != tail)
		{
			cout << cur->data;
			if (cur->next != tail)
				cout << ", ";
			cur = cur->next;
		}
	}
}

template <class itemType>
bool llSorted<itemType>::isFull()
{
	return (length == MAX_SIZE);
}

template <class itemType>
bool llSorted<itemType>::isEmpty()
{
	return (length == 0);
}

template <class itemType>
void llSorted<itemType>::InsertItem()
{
	// Check to see if the list is full
	if(isFull())
	{
		cout << "List is Full!\n" << endl;
		init();
	}
	// List is not full, ask user for value and insert sorted
	else
	{
		usrVal(0);
		// if list is empty, just insert it right after head
		if (isEmpty())
		{
			length++;
			cur->data = value;
			cur->next = NULL;
			tail = cur->next;
			cout << endl;
			init();
		}
		else
		{
			// Traverse the list til next is > the value
			cur = head->next;
			inserted = false;
			while (cur != NULL)
			{
				if (value > cur->data)
				{
					cur = cur->next;
				}
				else
				{
					cur = new node;
					cur->data = value;
					inserted = true;
					length++;
					break;
				}
			}
			if (!inserted)
			{
				cur = new node;
				cur->data = value;
				cur->next = NULL;
				tail = cur->next;
				length++;
			}
			cout << endl;
			init();
		}
	}
}

template <class itemType>
void llSorted<itemType>::RetrieveItem()
{
	// Check to see if the list is empty
	if(isEmpty())
	{
		cout << "List is empty!\n" << endl;
		init();
	}
	// List is not empty, ask user for value to find
	else
	{
		usrVal(1);
		// Traverse the list until tail is hit
		cur = head;
		index = 0;
		while (cur != tail)
		{
			if (cur->data == value)
			{
				found++;
				cout << "  Found! Properties of '" << cur->data << "':" << endl;
				cout << "  Address:\t\t\t" << &cur->data << endl;
				cout << "  Index:\t\t\t" << index << endl;
				if (cur->next != tail)
					cout << "  Next Address & Value:\t\t" << &cur->next << " = " << cur->next->data << endl;
				cur = cur->next;
			}
			else
				cur = cur->next;
			index++;
		}
		if(!found)
			cout << "Value does not exist!\n";
		cout << endl;
		init();
	}
}

template <class itemType>
void llSorted<itemType>::DeleteItem()
{
	// Check if list is empty
	if (isEmpty())
	{
		cout << "List is empty!" << endl;
		init();
	}
	// List is not empty, ask user for value and "delete" item
	else
	{
		usrVal(2);
		// traverse the list until you find the value
		cur = head;
		while(cur->next != tail)
		{
			// check if cur->next contains the value
			if(cur->next->data == value)
			{
				found++;
				length--;
				cur->next = cur->next->next;
			}
			else
				cur = cur->next;
		}
		if(!(found))
			cout << "Value does not exist!\n" << endl;
		cout << endl;
		init();
	}
}

template <class itemType>
void llSorted<itemType>::getLength()
{
	// offset by -1 due to NULL head
	cout << "Maximum number of items list can hold:\t" << MAX_SIZE - 1 << endl;
	cout << "Currently stored items:\t\t\t" << length - 1 << endl;
	cout << "Last selected index:\t\t\t";
	if (index == 0)
		cout << "None" << endl;
	else
		cout << index - 1 << endl;
	cout << endl;
	init();
}

template <class itemType>
void llSorted<itemType>::usrVal(int val)
{
	cout << "What integer would you like to ";
	if (val == 0)
		cout << "insert? ";
	else if (val == 1)
		cout << "retrieve? ";
	else
		cout << "delete? ";
	while (!(cin >> value))
	{
		cout << "Please enter only integer digits: ";
		cin.clear();
		cin.ignore(1000, 10);
	}
	// reset found to 0
	found = 0;
}

template <class itemType>
void llSorted<itemType>::validation()
{
	cout << "Invalid Command. Please try again.\n" << endl;
	init();
}

template <class itemType>
int llSorted<itemType>::exit()
{
	cout << "Good bye.";
	return 0;
}

Open in new window

I keep hearing this so I pass it onto you. It is not a rule, just some general guidance. Use as you see fit. (This guidance was not in our coding standard, and a large OO team did not encounter any problems with std. But, in general, you can see how there could be name clashes if you are not careful. But by following this guidance, you do not need to be careful, and that is considered a plus in Software Engineering.)
    http://www.parashift.com/c++-faq-lite/coding-standards.html#faq-27.5

Author

Commented:
Ah ok, at least now it makes sense =P

I'll change it to std::, maybe things will "magically" work that way haha
I'll take a look at your latest posting. Understand that the problems you describe in http:#33945398 using the alternative header approach does not solve compiler issues; just other logistic issues (as described in the faq). After solving the compiler issues, the alternative approaches will work.
Nope, using std:: will not likely fix anything. That guideline is primarily a SW Engineering maintainability issue and not usually a compiler software issue (at least not usually during initial development).

Author

Commented:
Understood, and all of this would be so much easier/simpler if there were no 3-file requirement on the project. I understand the usage of templates and what they are supposed to accomplish, but I cannot get back these linking errors, and it does not help that MSDN's linking error code database is so generalized, it's hard to narrow down or even figure out what to fix where.

Author

Commented:
>>Nope, using std:: will not likely fix anything. That guideline is primarily a SW Engineering maintainability >>issue and not usually a compiler software issue (at least not usually during initial development).

I was trying to give myself hope so I wouldn't feel like such a failure for not understanding the problem, but you ruined that for me too. Thanks.

I'm kidding, but it would be nice if it just clicked in my head what I'm doing wrong...
You are welcome. Einstein and Edison mostly failed. This is what happens when you attack difficult problems!
There's a Dilbert cartoon where the engineer says, he finally got the solution after a dozen tries. The manager then suggests that the engineer work on the last solution first to save everyone time, simple, eh!

Author

Commented:
Haha of course.

On the brighter side of things... What if we move the for loop to a different function, wouldn't that make the code at least compile?

Author

Commented:
The for loop in the constructor I mean.

Author

Commented:
Nevermind, did not work. I removed all the code from the for loop to the end of the function and still spits out the same error, saying data and temp cannot be void.

To my knowledge, the constructor function has to be void, but we change the datatype, the code no longer works. SO how can we make only the constructor void, and the rest a variable?
I suggest not guessing at this time. I found one problem. Let me look more over your code, and I'll make some suggestions.I suspect that you are close.

Author

Commented:
Ok, I'll await your response.
In your .cpp file:
>> template class llSorted<void>;

What you are saying to the compiler is that you want to generate code for a linked list using type void. Now,  that is difficult for the compiler to do. How much room should it allocate for your struct? It's just too difficult a problem for the compiler. So you get errors. But the good news is that there is an easy fix to it. BTW - looks like you should add this line at the end of the .cpp file so that all the methods can be generated.

Now if you kept to the first simpler approach of including the .cpp file in the .h file, then when your driver creates a linked list, the compiler will know how to generate the code.

Try it one way (any way you choose), and after you get it to compile, it will be very easy to convert to the two other alternatives described in the faq.

Author

Commented:
>>BTW - looks like you should add this line at the end of the .cpp file so that all the methods can be >>generated.

You mean the template class llSorted<void>; correct?

>> Now if you kept to the first simpler approach of including the .cpp file in the .h file, then when your >>driver creates a linked list, the compiler will know how to generate the code.

Like this (see code attached)? If so, these are the errors it gives me:

1>------ Build started: Project: Templetized sorted 2-way circular linked list, Configuration: Debug Win32 ------
1>  stdafx.cpp
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4): error C2143: syntax error : missing ';' before '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4): error C2988: unrecognizable template declaration/definition
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4): error C2059: syntax error : '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(62): error C2039: 'init' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(63): error C2143: syntax error : missing ';' before '{'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(63): error C2447: '{' : missing function header (old-style formal list?)
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(100): error C2143: syntax error : missing ';' before '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(100): error C2182: 'llSorted' : illegal use of type 'void'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(100): error C2086: 'int llSorted' : redefinition
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4) : see declaration of 'llSorted'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(100): error C2988: unrecognizable template declaration/definition
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(100): error C2059: syntax error : '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(100): error C2039: 'printList' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(118): error C2039: 'isFull' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(119): error C2143: syntax error : missing ';' before '{'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(119): error C2447: '{' : missing function header (old-style formal list?)
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(124): error C2143: syntax error : missing ';' before '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(124): error C2371: 'llSorted' : redefinition; different basic types
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4) : see declaration of 'llSorted'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(124): error C2988: unrecognizable template declaration/definition
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(124): error C2059: syntax error : '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(124): error C2039: 'isEmpty' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(130): error C2039: 'InsertItem' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(131): error C2143: syntax error : missing ';' before '{'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(131): error C2447: '{' : missing function header (old-style formal list?)
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(187): error C2143: syntax error : missing ';' before '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(187): error C2182: 'llSorted' : illegal use of type 'void'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(187): error C2086: 'int llSorted' : redefinition
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4) : see declaration of 'llSorted'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(187): error C2988: unrecognizable template declaration/definition
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(187): error C2059: syntax error : '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(187): error C2039: 'RetrieveItem' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(226): error C2039: 'DeleteItem' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(227): error C2143: syntax error : missing ';' before '{'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(227): error C2447: '{' : missing function header (old-style formal list?)
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(260): error C2143: syntax error : missing ';' before '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(260): error C2182: 'llSorted' : illegal use of type 'void'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(260): error C2086: 'int llSorted' : redefinition
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4) : see declaration of 'llSorted'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(260): error C2988: unrecognizable template declaration/definition
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(260): error C2059: syntax error : '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(260): error C2039: 'getLength' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(275): error C2039: 'usrVal' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(276): error C2143: syntax error : missing ';' before '{'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(276): error C2447: '{' : missing function header (old-style formal list?)
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(295): error C2143: syntax error : missing ';' before '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(295): error C2182: 'llSorted' : illegal use of type 'void'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(295): error C2086: 'int llSorted' : redefinition
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4) : see declaration of 'llSorted'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(295): error C2988: unrecognizable template declaration/definition
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(295): error C2059: syntax error : '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(295): error C2039: 'validation' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(302): error C2039: 'exit' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(303): error C2143: syntax error : missing ';' before '{'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(303): error C2447: '{' : missing function header (old-style formal list?)
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(308): error C2988: unrecognizable template declaration/definition
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(308): error C2059: syntax error : '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4): error C2143: syntax error : missing ';' before '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4): error C2086: 'int llSorted' : redefinition
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4) : see declaration of 'llSorted'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4): error C2988: unrecognizable template declaration/definition
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4): error C2059: syntax error : '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(62): error C2039: 'init' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(63): error C2143: syntax error : missing ';' before '{'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(63): error C2447: '{' : missing function header (old-style formal list?)
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(100): error C2143: syntax error : missing ';' before '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(100): error C2182: 'llSorted' : illegal use of type 'void'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(100): error C2086: 'int llSorted' : redefinition
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4) : see declaration of 'llSorted'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(100): error C2988: unrecognizable template declaration/definition
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(100): error C2059: syntax error : '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(100): error C2039: 'printList' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(118): error C2039: 'isFull' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(119): error C2143: syntax error : missing ';' before '{'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(119): error C2447: '{' : missing function header (old-style formal list?)
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(124): error C2143: syntax error : missing ';' before '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(124): error C2371: 'llSorted' : redefinition; different basic types
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4) : see declaration of 'llSorted'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(124): error C2988: unrecognizable template declaration/definition
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(124): error C2059: syntax error : '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(124): error C2039: 'isEmpty' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(130): error C2039: 'InsertItem' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(131): error C2143: syntax error : missing ';' before '{'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(131): error C2447: '{' : missing function header (old-style formal list?)
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(187): error C2143: syntax error : missing ';' before '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(187): error C2182: 'llSorted' : illegal use of type 'void'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(187): error C2086: 'int llSorted' : redefinition
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4) : see declaration of 'llSorted'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(187): error C2988: unrecognizable template declaration/definition
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(187): error C2059: syntax error : '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(187): error C2039: 'RetrieveItem' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(226): error C2039: 'DeleteItem' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(227): error C2143: syntax error : missing ';' before '{'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(227): error C2447: '{' : missing function header (old-style formal list?)
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(260): error C2143: syntax error : missing ';' before '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(260): error C2182: 'llSorted' : illegal use of type 'void'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(260): error C2086: 'int llSorted' : redefinition
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4) : see declaration of 'llSorted'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(260): error C2988: unrecognizable template declaration/definition
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(260): error C2059: syntax error : '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(260): error C2039: 'getLength' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(275): error C2039: 'usrVal' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(276): error C2143: syntax error : missing ';' before '{'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(276): error C2447: '{' : missing function header (old-style formal list?)
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(295): error C2143: syntax error : missing ';' before '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(295): error C2182: 'llSorted' : illegal use of type 'void'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(295): error C2086: 'int llSorted' : redefinition
1>          g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(4) : see declaration of 'llSorted'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(295): error C2988: unrecognizable template declaration/definition
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(295): error C2059: syntax error : '<'
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(295): error C2039: 'validation' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(302): error C2039: 'exit' : is not a member of '`global namespace''
1>g:\comsc-210 labs\7\templetized sorted 2-way circular linked list\llsorted.cpp(302): fatal error C1003: error count exceeds 100; stopping compilation
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

#ifndef LLSORTED_H
#define LLSORTED_H
#include "llSorted.cpp"

template <class itemType>
class llSorted
{
private:
	struct node
	{
		itemType data;
		node* next;
		node* prev;
	};
	node *head, *tail, *cur;
	int MAX_SIZE;
	int length;
	itemType temp;
	int index;
	int value;
	int cmd;
	bool found;
	bool inserted;

public:
	llSorted();
	bool isFull();
	bool isEmpty();
	void init();
	void printList();
	void InsertItem();
	void RetrieveItem();
	void DeleteItem();
	void getLength();
	void usrVal(int);
	void validation();
	int exit();

};

#endif

Open in new window

Ok, no biggie. You are mixing up two different approaches.
Sticking with the alternative approach, remove from .h:
   #include "llSorted.cpp"
(And if you did want to use this approach, then remember that the implementation is defined after the class.)

In the .cpp file, you need to include the .h file (before the implementation).
In the .cpp file, you need to add the line:
    template class llSorted<int>;
and similar lines for any other data types for which you need a linked list.

Author

Commented:
>>In the .cpp file, you need to include the .h file (before the implementation).

If this is already included in the stdafx.h file, why would I need to include it again in the .cpp file
(see attached code for stdafx.h file)
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//

#pragma once

#include "llSorted.h"
#include "llSorted.cpp"

#include <iostream>
#include <cstdlib>
#include <ctime>

using std::cout;
using std::cin;
using std::endl;

Open in new window

Author

Commented:
>>In the .cpp file, you need to add the line:
>>    template class llSorted<int>;
>>and similar lines for any other data types for which you need a linked list.

Update:
added template class types at the bottom of file as instructed.
#include "stdafx.h"

template <class itemType>
llSorted<itemType>::llSorted()
{
	srand(time(0));

	head = NULL;
	tail = NULL;
	cur = NULL;
	index = 0;
	MAX_SIZE = 11;
	length = rand() % 10 + 1;
	cmd = 0;
	for (int i = 0; i < length; i++)
	{
		if (head == NULL)
		{
			head = new node;
			head->data = rand() % 101;
			head->next = new node;
			head->prev = NULL;
			cur = head->next;
			cur->prev = head;
		}
		else
		{
			cur->data = rand() % 101;
			cur->next = new node;
			cur->next->prev = cur;
			cur = cur->next;
		}
	}
	tail = cur;
	tail->next = head;
	head->prev = tail;

	// sort the list
	if (head != NULL)
	{
		cur = head;
		for (int i = 0; i < length; i++)
		{
			for (int j = 0; j < length; j++)
			{
				if (cur->next != tail)
				{
					if (cur->data > cur->next->data)
					{
						temp = cur->data;
						cur->data = cur->next->data;
						cur->next->data = temp;
					}
				}
				cur = cur->next;
			}
		}
	}
}

template <class itemType>
void llSorted<itemType>::init()
{
	printList();
	cout << "\nAvailable Commands:\n  1. Insert Item\n  2. Retrieve Item\n  3. Delete Item\n  4. List Details\n  9. Select Different Implementation\n  0. Exit\n\nCommand: ";
	while(!(cin >> cmd))
	{
		cout << "Please enter only the number associated with the command\nCommand: ";
		cin.clear();
		cin.ignore(1000, 10);
	}

	switch (cmd)
	{
	case 1:
		InsertItem();
		break;
	case 2:
		RetrieveItem();
		break;
	case 3:
		DeleteItem();
		break;
	case 4:
		getLength();
		break;
	case 9:
		init();
		break;
	case 0:
		exit();
		break;
	default:
		validation();
		break;
	}
}

template <class itemType>
void llSorted<itemType>::printList()
{
	cout << "List: ";
	// memory issue if list is empty
	if (!(isEmpty()))
	{
		cur = head;
		while (cur != tail)
		{
			cout << cur->data;
			if (cur->next != tail)
				cout << ", ";
			cur = cur->next;
		}
	}
}

template <class itemType>
bool llSorted<itemType>::isFull()
{
	return (length == MAX_SIZE);
}

template <class itemType>
bool llSorted<itemType>::isEmpty()
{
	return (length == 0);
}

template <class itemType>
void llSorted<itemType>::InsertItem()
{
	// Check to see if the list is full
	if(isFull())
	{
		cout << "List is Full!\n" << endl;
		init();
	}
	// List is not full, ask user for value and insert sorted
	else
	{
		usrVal(0);
		// if list is empty, just insert it right after head
		if (isEmpty())
		{
			length++;
			cur->data = value;
			cur->next = NULL;
			tail = cur->next;
			cout << endl;
			init();
		}
		else
		{
			// Traverse the list til next is > the value
			cur = head->next;
			inserted = false;
			while (cur != NULL)
			{
				if (value > cur->data)
				{
					cur = cur->next;
				}
				else
				{
					cur = new node;
					cur->data = value;
					inserted = true;
					length++;
					break;
				}
			}
			if (!inserted)
			{
				cur = new node;
				cur->data = value;
				cur->next = NULL;
				tail = cur->next;
				length++;
			}
			cout << endl;
			init();
		}
	}
}

template <class itemType>
void llSorted<itemType>::RetrieveItem()
{
	// Check to see if the list is empty
	if(isEmpty())
	{
		cout << "List is empty!\n" << endl;
		init();
	}
	// List is not empty, ask user for value to find
	else
	{
		usrVal(1);
		// Traverse the list until tail is hit
		cur = head;
		index = 0;
		while (cur != tail)
		{
			if (cur->data == value)
			{
				found++;
				cout << "  Found! Properties of '" << cur->data << "':" << endl;
				cout << "  Address:\t\t\t" << &cur->data << endl;
				cout << "  Index:\t\t\t" << index << endl;
				if (cur->next != tail)
					cout << "  Next Address & Value:\t\t" << &cur->next << " = " << cur->next->data << endl;
				cur = cur->next;
			}
			else
				cur = cur->next;
			index++;
		}
		if(!found)
			cout << "Value does not exist!\n";
		cout << endl;
		init();
	}
}

template <class itemType>
void llSorted<itemType>::DeleteItem()
{
	// Check if list is empty
	if (isEmpty())
	{
		cout << "List is empty!" << endl;
		init();
	}
	// List is not empty, ask user for value and "delete" item
	else
	{
		usrVal(2);
		// traverse the list until you find the value
		cur = head;
		while(cur->next != tail)
		{
			// check if cur->next contains the value
			if(cur->next->data == value)
			{
				found++;
				length--;
				cur->next = cur->next->next;
			}
			else
				cur = cur->next;
		}
		if(!(found))
			cout << "Value does not exist!\n" << endl;
		cout << endl;
		init();
	}
}

template <class itemType>
void llSorted<itemType>::getLength()
{
	// offset by -1 due to NULL head
	cout << "Maximum number of items list can hold:\t" << MAX_SIZE - 1 << endl;
	cout << "Currently stored items:\t\t\t" << length - 1 << endl;
	cout << "Last selected index:\t\t\t";
	if (index == 0)
		cout << "None" << endl;
	else
		cout << index - 1 << endl;
	cout << endl;
	init();
}

template <class itemType>
void llSorted<itemType>::usrVal(int val)
{
	cout << "What integer would you like to ";
	if (val == 0)
		cout << "insert? ";
	else if (val == 1)
		cout << "retrieve? ";
	else
		cout << "delete? ";
	while (!(cin >> value))
	{
		cout << "Please enter only integer digits: ";
		cin.clear();
		cin.ignore(1000, 10);
	}
	// reset found to 0
	found = 0;
}

template <class itemType>
void llSorted<itemType>::validation()
{
	cout << "Invalid Command. Please try again.\n" << endl;
	init();
}

template <class itemType>
int llSorted<itemType>::exit()
{
	cout << "Good bye.";
	return 0;
}

template class llSorted<void>;
template class llSorted<int>;
template class llSorted<char>;

Open in new window

Any chance you can build a project without stdafx.h, at least for now?

Author

Commented:
Don't know, every time I tried it without stdafx.h it gave me errors
What are you using to build? I am using VS 2008 Express.

Author

Commented:
Ok, got it to work without stdafx.h, but still gives me the same errors

Author

Commented:
VS 2010 Pro

Author

Commented:
Updated .cpp files (no stdafx)
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "llSorted.h"
using std::cout;
using std::cin;
using std::endl;

template <class itemType>
llSorted<itemType>::llSorted()
{
	srand(time(0));

	head = NULL;
	tail = NULL;
	cur = NULL;
	index = 0;
	MAX_SIZE = 11;
	length = rand() % 10 + 1;
	cmd = 0;
	for (int i = 0; i < length; i++)
	{
		if (head == NULL)
		{
			head = new node;
			head->data = rand() % 101;
			head->next = new node;
			head->prev = NULL;
			cur = head->next;
			cur->prev = head;
		}
		else
		{
			cur->data = rand() % 101;
			cur->next = new node;
			cur->next->prev = cur;
			cur = cur->next;
		}
	}
	tail = cur;
	tail->next = head;
	head->prev = tail;

	// sort the list
	if (head != NULL)
	{
		cur = head;
		for (int i = 0; i < length; i++)
		{
			for (int j = 0; j < length; j++)
			{
				if (cur->next != tail)
				{
					if (cur->data > cur->next->data)
					{
						temp = cur->data;
						cur->data = cur->next->data;
						cur->next->data = temp;
					}
				}
				cur = cur->next;
			}
		}
	}
}

template <class itemType>
void llSorted<itemType>::init()
{
	printList();
	cout << "\nAvailable Commands:\n  1. Insert Item\n  2. Retrieve Item\n  3. Delete Item\n  4. List Details\n  9. Select Different Implementation\n  0. Exit\n\nCommand: ";
	while(!(cin >> cmd))
	{
		cout << "Please enter only the number associated with the command\nCommand: ";
		cin.clear();
		cin.ignore(1000, 10);
	}

	switch (cmd)
	{
	case 1:
		InsertItem();
		break;
	case 2:
		RetrieveItem();
		break;
	case 3:
		DeleteItem();
		break;
	case 4:
		getLength();
		break;
	case 9:
		init();
		break;
	case 0:
		exit();
		break;
	default:
		validation();
		break;
	}
}

template <class itemType>
void llSorted<itemType>::printList()
{
	cout << "List: ";
	// memory issue if list is empty
	if (!(isEmpty()))
	{
		cur = head;
		while (cur != tail)
		{
			cout << cur->data;
			if (cur->next != tail)
				cout << ", ";
			cur = cur->next;
		}
	}
}

template <class itemType>
bool llSorted<itemType>::isFull()
{
	return (length == MAX_SIZE);
}

template <class itemType>
bool llSorted<itemType>::isEmpty()
{
	return (length == 0);
}

template <class itemType>
void llSorted<itemType>::InsertItem()
{
	// Check to see if the list is full
	if(isFull())
	{
		cout << "List is Full!\n" << endl;
		init();
	}
	// List is not full, ask user for value and insert sorted
	else
	{
		usrVal(0);
		// if list is empty, just insert it right after head
		if (isEmpty())
		{
			length++;
			cur->data = value;
			cur->next = NULL;
			tail = cur->next;
			cout << endl;
			init();
		}
		else
		{
			// Traverse the list til next is > the value
			cur = head->next;
			inserted = false;
			while (cur != NULL)
			{
				if (value > cur->data)
				{
					cur = cur->next;
				}
				else
				{
					cur = new node;
					cur->data = value;
					inserted = true;
					length++;
					break;
				}
			}
			if (!inserted)
			{
				cur = new node;
				cur->data = value;
				cur->next = NULL;
				tail = cur->next;
				length++;
			}
			cout << endl;
			init();
		}
	}
}

template <class itemType>
void llSorted<itemType>::RetrieveItem()
{
	// Check to see if the list is empty
	if(isEmpty())
	{
		cout << "List is empty!\n" << endl;
		init();
	}
	// List is not empty, ask user for value to find
	else
	{
		usrVal(1);
		// Traverse the list until tail is hit
		cur = head;
		index = 0;
		while (cur != tail)
		{
			if (cur->data == value)
			{
				found++;
				cout << "  Found! Properties of '" << cur->data << "':" << endl;
				cout << "  Address:\t\t\t" << &cur->data << endl;
				cout << "  Index:\t\t\t" << index << endl;
				if (cur->next != tail)
					cout << "  Next Address & Value:\t\t" << &cur->next << " = " << cur->next->data << endl;
				cur = cur->next;
			}
			else
				cur = cur->next;
			index++;
		}
		if(!found)
			cout << "Value does not exist!\n";
		cout << endl;
		init();
	}
}

template <class itemType>
void llSorted<itemType>::DeleteItem()
{
	// Check if list is empty
	if (isEmpty())
	{
		cout << "List is empty!" << endl;
		init();
	}
	// List is not empty, ask user for value and "delete" item
	else
	{
		usrVal(2);
		// traverse the list until you find the value
		cur = head;
		while(cur->next != tail)
		{
			// check if cur->next contains the value
			if(cur->next->data == value)
			{
				found++;
				length--;
				cur->next = cur->next->next;
			}
			else
				cur = cur->next;
		}
		if(!(found))
			cout << "Value does not exist!\n" << endl;
		cout << endl;
		init();
	}
}

template <class itemType>
void llSorted<itemType>::getLength()
{
	// offset by -1 due to NULL head
	cout << "Maximum number of items list can hold:\t" << MAX_SIZE - 1 << endl;
	cout << "Currently stored items:\t\t\t" << length - 1 << endl;
	cout << "Last selected index:\t\t\t";
	if (index == 0)
		cout << "None" << endl;
	else
		cout << index - 1 << endl;
	cout << endl;
	init();
}

template <class itemType>
void llSorted<itemType>::usrVal(int val)
{
	cout << "What integer would you like to ";
	if (val == 0)
		cout << "insert? ";
	else if (val == 1)
		cout << "retrieve? ";
	else
		cout << "delete? ";
	while (!(cin >> value))
	{
		cout << "Please enter only integer digits: ";
		cin.clear();
		cin.ignore(1000, 10);
	}
	// reset found to 0
	found = 0;
}

template <class itemType>
void llSorted<itemType>::validation()
{
	cout << "Invalid Command. Please try again.\n" << endl;
	init();
}

template <class itemType>
int llSorted<itemType>::exit()
{
	cout << "Good bye.";
	return 0;
}

template class llSorted<void>;
template class llSorted<int>;
template class llSorted<char>;

Open in new window

Ok, to make sure I see exactly what you see, please submit the three files separately. (At this point, there should be no stdafx.h based on what you said.) I'll build the project and let you know. There is probably one small step is missing.

Author

Commented:
Ok, i'll make 3 posts following this one containing the code for each file

Author

Commented:
Driver File: (int main)
// driver file

#include <iostream>
#include "llSorted.h"

int main()
{
	llSorted<int> templatize;
	
	templatize.init();
}

Open in new window

Author

Commented:
Header file: (llSorted.h)
// header file

#ifndef LLSORTED_H
#define LLSORTED_H

template <class itemType>
class llSorted
{
private:
	struct node
	{
		itemType data;
		node* next;
		node* prev;
	};
	node *head, *tail, *cur;
	int MAX_SIZE;
	int length;
	itemType temp;
	int index;
	int value;
	int cmd;
	bool found;
	bool inserted;

public:
	llSorted();
	bool isFull();
	bool isEmpty();
	void init();
	void printList();
	void InsertItem();
	void RetrieveItem();
	void DeleteItem();
	void getLength();
	void usrVal(int);
	void validation();
	int exit();

};

#endif

Open in new window

Author

Commented:
Implementation file: (llSorted.cpp)
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "llSorted.h"
using std::cout;
using std::cin;
using std::endl;

template <class itemType>
llSorted<itemType>::llSorted()
{
	srand(time(0));

	head = NULL;
	tail = NULL;
	cur = NULL;
	index = 0;
	MAX_SIZE = 11;
	length = rand() % 10 + 1;
	cmd = 0;
	for (int i = 0; i < length; i++)
	{
		if (head == NULL)
		{
			head = new node;
			head->data = rand() % 101;
			head->next = new node;
			head->prev = NULL;
			cur = head->next;
			cur->prev = head;
		}
		else
		{
			cur->data = rand() % 101;
			cur->next = new node;
			cur->next->prev = cur;
			cur = cur->next;
		}
	}
	tail = cur;
	tail->next = head;
	head->prev = tail;

	// sort the list
	if (head != NULL)
	{
		cur = head;
		for (int i = 0; i < length; i++)
		{
			for (int j = 0; j < length; j++)
			{
				if (cur->next != tail)
				{
					if (cur->data > cur->next->data)
					{
						temp = cur->data;
						cur->data = cur->next->data;
						cur->next->data = temp;
					}
				}
				cur = cur->next;
			}
		}
	}
}

template <class itemType>
void llSorted<itemType>::init()
{
	printList();
	cout << "\nAvailable Commands:\n  1. Insert Item\n  2. Retrieve Item\n  3. Delete Item\n  4. List Details\n  9. Select Different Implementation\n  0. Exit\n\nCommand: ";
	while(!(cin >> cmd))
	{
		cout << "Please enter only the number associated with the command\nCommand: ";
		cin.clear();
		cin.ignore(1000, 10);
	}

	switch (cmd)
	{
	case 1:
		InsertItem();
		break;
	case 2:
		RetrieveItem();
		break;
	case 3:
		DeleteItem();
		break;
	case 4:
		getLength();
		break;
	case 9:
		init();
		break;
	case 0:
		exit();
		break;
	default:
		validation();
		break;
	}
}

template <class itemType>
void llSorted<itemType>::printList()
{
	cout << "List: ";
	// memory issue if list is empty
	if (!(isEmpty()))
	{
		cur = head;
		while (cur != tail)
		{
			cout << cur->data;
			if (cur->next != tail)
				cout << ", ";
			cur = cur->next;
		}
	}
}

template <class itemType>
bool llSorted<itemType>::isFull()
{
	return (length == MAX_SIZE);
}

template <class itemType>
bool llSorted<itemType>::isEmpty()
{
	return (length == 0);
}

template <class itemType>
void llSorted<itemType>::InsertItem()
{
	// Check to see if the list is full
	if(isFull())
	{
		cout << "List is Full!\n" << endl;
		init();
	}
	// List is not full, ask user for value and insert sorted
	else
	{
		usrVal(0);
		// if list is empty, just insert it right after head
		if (isEmpty())
		{
			length++;
			cur->data = value;
			cur->next = NULL;
			tail = cur->next;
			cout << endl;
			init();
		}
		else
		{
			// Traverse the list til next is > the value
			cur = head->next;
			inserted = false;
			while (cur != NULL)
			{
				if (value > cur->data)
				{
					cur = cur->next;
				}
				else
				{
					cur = new node;
					cur->data = value;
					inserted = true;
					length++;
					break;
				}
			}
			if (!inserted)
			{
				cur = new node;
				cur->data = value;
				cur->next = NULL;
				tail = cur->next;
				length++;
			}
			cout << endl;
			init();
		}
	}
}

template <class itemType>
void llSorted<itemType>::RetrieveItem()
{
	// Check to see if the list is empty
	if(isEmpty())
	{
		cout << "List is empty!\n" << endl;
		init();
	}
	// List is not empty, ask user for value to find
	else
	{
		usrVal(1);
		// Traverse the list until tail is hit
		cur = head;
		index = 0;
		while (cur != tail)
		{
			if (cur->data == value)
			{
				found++;
				cout << "  Found! Properties of '" << cur->data << "':" << endl;
				cout << "  Address:\t\t\t" << &cur->data << endl;
				cout << "  Index:\t\t\t" << index << endl;
				if (cur->next != tail)
					cout << "  Next Address & Value:\t\t" << &cur->next << " = " << cur->next->data << endl;
				cur = cur->next;
			}
			else
				cur = cur->next;
			index++;
		}
		if(!found)
			cout << "Value does not exist!\n";
		cout << endl;
		init();
	}
}

template <class itemType>
void llSorted<itemType>::DeleteItem()
{
	// Check if list is empty
	if (isEmpty())
	{
		cout << "List is empty!" << endl;
		init();
	}
	// List is not empty, ask user for value and "delete" item
	else
	{
		usrVal(2);
		// traverse the list until you find the value
		cur = head;
		while(cur->next != tail)
		{
			// check if cur->next contains the value
			if(cur->next->data == value)
			{
				found++;
				length--;
				cur->next = cur->next->next;
			}
			else
				cur = cur->next;
		}
		if(!(found))
			cout << "Value does not exist!\n" << endl;
		cout << endl;
		init();
	}
}

template <class itemType>
void llSorted<itemType>::getLength()
{
	// offset by -1 due to NULL head
	cout << "Maximum number of items list can hold:\t" << MAX_SIZE - 1 << endl;
	cout << "Currently stored items:\t\t\t" << length - 1 << endl;
	cout << "Last selected index:\t\t\t";
	if (index == 0)
		cout << "None" << endl;
	else
		cout << index - 1 << endl;
	cout << endl;
	init();
}

template <class itemType>
void llSorted<itemType>::usrVal(int val)
{
	cout << "What integer would you like to ";
	if (val == 0)
		cout << "insert? ";
	else if (val == 1)
		cout << "retrieve? ";
	else
		cout << "delete? ";
	while (!(cin >> value))
	{
		cout << "Please enter only integer digits: ";
		cin.clear();
		cin.ignore(1000, 10);
	}
	// reset found to 0
	found = 0;
}

template <class itemType>
void llSorted<itemType>::validation()
{
	cout << "Invalid Command. Please try again.\n" << endl;
	init();
}

template <class itemType>
int llSorted<itemType>::exit()
{
	cout << "Good bye.";
	return 0;
}

template class llSorted<void>;
template class llSorted<int>;
template class llSorted<char>;

Open in new window

Author

Commented:
Just for clarification, the error after compiling the 3 files above with VS 2010 Pro, is:
1>------ Build started: Project: testEmptyProj, Configuration: Debug Win32 ------
1>  llSorted.cpp
1>g:\comsc-210 labs\testemptyproj\llsorted.h(17): error C2182: 'temp' : illegal use of type 'void'
1>          g:\comsc-210 labs\testemptyproj\llsorted.cpp(314) : see reference to class template instantiation 'llSorted<itemType>' being compiled
1>          with
1>          [
1>              itemType=void
1>          ]
1>g:\comsc-210 labs\testemptyproj\llsorted.h(10): error C2182: 'data' : illegal use of type 'void'
1>          g:\comsc-210 labs\testemptyproj\llsorted.cpp(314) : see reference to class template instantiation 'llSorted<itemType>::node' being compiled
1>          with
1>          [
1>              itemType=void
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Open in new window

Author

Commented:
Comment out line 314:
     template class llSorted<void>;

and it works
line 314 in llSorted.cpp
void?
Ok, very good!
Any questions about what we did?

Author

Commented:
Actually, yes. The constructor needs to void doesn't it? It's technically not since it is of type itemType... so why does this work?
If you later try the first approach (i.e., including the .cpp file in the .h file):
1) There are now two compilation units rather than three (so change your project)
2) You do not use these lines in your .cpp file:
template class llSorted<int>;
template class llSorted<char>;
>> The constructor needs to void doesn't it?
Sorry, could you elaborate on this question. I'm not understanding.
BTW - I got a warning which I fix with this:
     srand((unsigned int)time(0));

Author

Commented:
Understood, but like i said, my understanding of the constructor function is that it needs to be void, but if we do, say int, doesn't that technically make the constructor int as well? Well I mean, obviously it doesn't since it compiles and runs, just trying to figure out why it does

Author

Commented:
>>BTW - I got a warning which I fix with this:
>>     srand((unsigned int)time(0));

Thanks, I was wondering what the fix for that was.
>> my understanding of the constructor function is that it needs to be void
Probably would be helpful to me to learn exactly where you got this understanding. I'm not sure exactly what it means to say that a constructor (which is not a function) needs to be void. If you provide a reference where I can see this idea of "needs to be void", maybe I can put things in context.

I think you are saying that you believe we need this:
   template class llSorted<void>;
and you do not understand why this works without it.

Just to generalize, your constructor
  template <class itemType>
  llSorted<itemType>::llSorted()

is generically defined to be of some type, itemType. When the compiler sees
    template class llSorted<int>;
    template class llSorted<char>;
it sees that it needs to write code substituting int for itemType, and another chunk of code substituting char for itemType. You could do this manually instead of using templates, but that is a lot of copy and pasting.

Author

Commented:
Ah ok, I understand now. I was thinking constructors were actual functions with no return type (thus void in my eyes). It makes sense now, and only took 4 days and 3 lines of code lol.

Thanks =)
You are very welcome.

It will take a little longer if you try to go back to the first approach, just to see if you can do it. That may actually help you consolidate some of the concepts.
For your next question, I would create your own class and try creating a linked list using that. You will get some errors that may surprise you. So far, for simple number types such as int or double, your program may templatize OK.

Author

Commented:
Yea I plan to, for future reference. I'm sure I'll be using templates more often now that I understand how they work.

Author

Commented:
>>For your next question, I would create your own class and try creating a linked list using that. You will >>get some errors that may surprise you. So far, for simple number types such as int or double, your >>program may templatize OK.

Actually, I was just about to open a new question, since this template needs to be compatible for ints, chars, floats, doubles, and strings
>> and only took 4 days and 3 lines of code lol.
Well, one day didn't count because of your W7 dump.
3 LOCs! Amazing, isn't it. And the ordering of the lines. The reasoning behind it can be quite confusing. :)

Author

Commented:
>>The reasoning behind it can be quite confusing.

Indeed, but that was Stroustrup's plan with C++ all along wasn't it? =P
>> since this template needs to be compatible for ints, chars, floats, doubles, and strings
Well, if you want to learn more, you could even try to make it compatible with
struct Personal_Record {
   string employee_name;
   unsigned int age;
   unsigned int employee_id;
   unsigned int supervisor_id;
   //...
}

Another question you could ask has nothing to do with templates. It's more to get tips towards improved OO design (when you just used int and no template).
>> Indeed, but that was Stroustrup's plan with C++ all along wasn't it? =P
Oh, I see you have read the leaked document showing the truth behind the creation of C++
     http://www.erenkrantz.com/Humor/FakeIEEEStroustrupInterview.shtml

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial