# C++ error LNK2028: unresolved token



## Gibson56 (Dec 21, 2007)

Im writing a program that incorporates using a MultiLinkedList however im having a problem with a few things. I got down to the point where I only have 2 errors however I dont know how to fix these last ones. 

Error 1: error LNK2028: unresolved token (0A0003AF) "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class MultiListADT<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,100> &)" ([email protected][email protected][email protected]@[email protected]@@[email protected]@AAV[email protected][email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@@Z) referenced in function "int __cdecl main(void)" ([email protected]@$$HYAHXZ)

Error 2: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class MultiListADT<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,100> &)" ([email protected][email protected][email protected]@[email protected]@@[email protected]@[email protected][email protected][email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@@@Z) referenced in function "int __cdecl main(void)" ([email protected]@$$HYAHXZ)

and the files
NodeADT.h

```
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

const int null = 0;

template<class TYPE, int threads>
class MultiListADT;

template <class TYPE, int threads>
class NodeADT
{
public:
	NodeADT();
	NodeADT(TYPE);
	~NodeADT();
	TYPE getInfo();
	NodeADT<TYPE, threads>* getPrevious(int=0);
	NodeADT<TYPE, threads>* getNext(int=0);
	void setNext(NodeADT<TYPE, threads>*,int=0);
	void setPrevious(NodeADT<TYPE, threads>*,int=0);
	bool Search(TYPE, bool=true,int=0);
	void AddToFront(TYPE item);
	void AddToRear(TYPE item);
	void InsertInOrder(TYPE);
	bool Delete(TYPE);
	friend ostream& operator << (ostream&, MultiListADT<TYPE, threads>&);
private:
	string info;
	NodeADT<TYPE, threads>* prev[threads];
	NodeADT<TYPE, threads>* next[threads];
};

template <class TYPE,int threads>
NodeADT<TYPE,threads>::NodeADT()
{
	prev[threads] = null;
	next[threads] = null;
}

template <class TYPE,int threads>
NodeADT<TYPE,threads>::NodeADT(TYPE item)
{
	info = item;
	prev = null;
	next = null;
}

template <class TYPE,int threads>
NodeADT<TYPE,threads>::~NodeADT()
{
	delete next[threads];
}

template <class TYPE,int threads>
TYPE NodeADT<TYPE,threads>::getInfo()
{
	return info;
}

template <class TYPE,int threads>
NodeADT<TYPE,threads>* NodeADT<TYPE,threads>::getNext(int i)
{
	return next[i];
}

template <class TYPE,int threads>
NodeADT<TYPE,threads>* NodeADT<TYPE,threads>::getPrevious(int i)
{
	return prev[i];
}

template <class TYPE,int threads>
bool NodeADT<TYPE,threads>::Search(TYPE value, bool forward,int i)
{
	if (forward && next[i] == 0)
		return false;
	else if (!forward && prev[i] == 0)
		return false;
	else
	{
		if (info.find(value) != string::npos)			//value==info
			return true;
		else if (forward)
			return next[threads]->Search(value, forward);
		else
			return prev[threads]->Search(value, forward);
	}
}

template <class TYPE,int threads>
void NodeADT<TYPE,threads>::setNext(NodeADT* nxt,int i)
{
	next[threads] = nxt;
}

template <class TYPE,int threads>
void NodeADT<TYPE,threads>::setPrevious(NodeADT* pre, int i)
{
	prev[threads] = pre;
}

template <class TYPE,int threads>
void NodeADT<TYPE,threads>::AddToFront(TYPE item)
{
	NodeADT<TYPE,threads> *temp = new NodeADT<TYPE,threads>;
	temp->info = item;
	temp->prev[threads] = this;
	temp->next[threads] = next[threads];
	next[threads]->prev[threads] = temp;
	next[threads] = temp;
}

template <class TYPE,int threads>
void NodeADT<TYPE,threads>::AddToRear(TYPE item)
{
	NodeADT<TYPE> *temp = new NodeADT<TYPE>;
	temp->info = item;
	temp->next = this;
	temp->prev = prev;
	prev->next = temp;
	prev = temp;
}

template <class TYPE,int threads>
void NodeADT<TYPE,threads>::InsertInOrder(TYPE item)
{
	if (next == null || info > item)
	{
		NodeADT *temp = new NodeADT(item);
		temp->next = this;
		temp->prev = prev;
		prev->next = temp;
		prev = temp;
	}
	else
		next->InsertInOrder(item);
}

template <class TYPE,int threads>
bool NodeADT<TYPE,threads>::Delete(TYPE item)
{
	if (next[threads] == null)
		return false;
	else if (info == item)
	{
		NodeADT *temp = this;
		prev[threads]->setNext(next[threads]);
		if (next[threads] != null)
			next[threads]->setPrevious(prev[threads]);
		next[threads] = null;
		delete temp;
		return true;
	}
	else
		return next[threads]->Delete(item);
}
```
MultiListADT.h

```
#include <iostream>
#include <fstream>
#include "NodeADT.h"
#include <string>

using namespace std;

template <class TYPE,int threads>
class MultiListADT
{
public:
	TYPE myarray [threads];
	/** Constructor **/
	MultiListADT();
	
	/** Destructor **/
	~MultiListADT();

	/** Declare accessors (observers) **/
	void ResetListForward();
	void ResetListBackward();
	bool IsEmpty();
	int LengthIs();
	bool Search(string, bool=true);
	void GetNextItem(TYPE &);
	void GetPreviousItem(TYPE &);
	int GetInfo();
	friend ostream& operator << (ostream&, MultiListADT<TYPE, threads>&);

	/** Declare mutators (transformers) **/
	void MakeEmpty();
	void AddToFront(TYPE);
	void AddToRear(TYPE);
	void InsertInOrder(TYPE);
	void Delete(TYPE);
	void Sort();



private:
	NodeADT<TYPE,threads>* head;
	NodeADT<TYPE,threads>* tail;
	int length;
	NodeADT<TYPE,threads>* currentNode;
};

template <class TYPE,int threads>
MultiListADT<TYPE,threads>::MultiListADT()
{
	head = new NodeADT<string,threads>(); 
	tail = new NodeADT<string,threads>();
	head->setNext(tail);
	tail->setPrevious(head);
	length = 0;
}

template <class TYPE,int threads>
MultiListADT<TYPE,threads>::~MultiListADT()
{
	delete head;

}

template <class TYPE,int threads>
bool MultiListADT<TYPE,threads>::IsEmpty()
{

	return head->getNext()==tail;

}

template <class TYPE,int threads>
int MultiListADT<TYPE,threads>::LengthIs()
{
	return length;
}

template <class TYPE,int threads>
void MultiListADT<TYPE,threads>::ResetListForward()
{
	if (!IsEmpty())
		currentNode = head->getNext();
}

template <class TYPE,int threads>
void MultiListADT<TYPE,threads>::ResetListBackward()
{
	if (!IsEmpty())
		currentNode = tail->getPrevious();
}

template <class TYPE,int threads>
bool MultiListADT<TYPE,threads>::Search(string value, bool forward)
{
	return head->Search(value, forward);
}

template <class TYPE,int threads>
int MultiListADT<TYPE,threads>::GetInfo()
{
	return currentNode->getInfo();
}

template <class TYPE,int threads>
void MultiListADT<TYPE,threads>::GetNextItem(TYPE &item)
{
	if (currentNode->getNext()!=null)
	{
		item = currentNode->getInfo();
		currentNode = currentNode->getNext();
	}
}

template <class TYPE,int threads>
void MultiListADT<TYPE,threads>::GetPreviousItem(TYPE &item)
{
	if (currentNode->getPrevious()!=null)
	{
		item = currentNode->getInfo();
		currentNode = currentNode->getPrevious();
	}
}


template <class TYPE,int threads>
void MultiListADT<TYPE,threads>::MakeEmpty()
{

	delete head;
	head = new NodeADT<string,threads>(); // or head = null;
	tail = new NodeADT<string,threads>();
	head->setNext(tail);
	tail->setPrevious(head);
	length = 0;

}

template <class TYPE,int threads>
void MultiListADT<TYPE,threads>::AddToFront(TYPE item)
{
	head->AddToFront(item);

	length++;
}

template <class TYPE,int threads>
void MultiListADT<TYPE,threads>::AddToRear(TYPE item)
{
	tail->AddToRear(item);
}

//Precondition:  The items in the linked list object are already in ascending order
//Postcondition: The new item is inserted in the list so as to preserve the ascending order
template <class TYPE,int threads>
void MultiListADT<TYPE,threads>::InsertInOrder(TYPE item)
{
	head->getNext()->InsertInOrder(item);
	length++;
}

template <class TYPE,int threads>
void MultiListADT<TYPE,threads>::Delete(TYPE item)
{
	if (head->getNext()->Delete(item))  //send the job to the second node
		length--;
}

template <class TYPE,int threads>
ostream& operator << (ostream& out, MultiListADT<string,threads> &theList)
{
	NodeADT<string> *temp = theList.head->next;

	while (temp->next != 0)
	{
		cout << temp->info << " ";
		temp = temp->next;
	}
	return out;
}
```
and main

```
#include <iostream>
#include "MultiListADT.h"
#include <fstream>
#include <string>

using namespace std;

void main(void)
{
	MultiListADT<string,100> myList;
	string item;
	ifstream data;
	string input;

	data.open("input.txt");

	while (!data.eof())
	{
		getline(data,input);
		myList.AddToFront(input);
	}

	cout << myList << endl;

	bool found;

	item = "Lu";
	cout << "Searching for 4..." << flush;
	found = myList.Search(item, true);
	if (found)
		cout << endl << "4 was found" << endl;
	else
		cout << endl << "There appears to be a problem with RetrieveItem" << endl;

	item = "Tammet";
	cout << "Searching for 6..." << flush;
	found = myList.Search(item, false);
	if (!found)
		cout << endl << "6 was not found" << endl;
	else
		cout << endl << "There appears to be a problem with RetrieveItem" << endl;

	item = "Asia";
	myList.Delete(item);
	found = myList.Search(item, true);
	if (!found)
		cout << endl << "1 was not found" << endl;
	else
		cout << endl << "There appears to be a problem with DeleteItem" << endl;

	item = "4";
	cout << "Searching for 4..." << flush;
	myList.Delete(item);
	found = myList.Search(item, true);
	if (!found)
		cout << endl << "4 was not found" << endl;
	else
		cout << endl << "There appears to be a problem with DeleteItem" << endl;

	myList.MakeEmpty();
	if (myList.IsEmpty())
		cout << endl << "MakeEmpty and IsEmpty appear to be working" << endl;
	else
		cout << endl << "There is a problem with MakeEmpty or IsEmpty" << endl;
	
	system("pause");
}
```
Im guessing it has to do something with ostream and the operator overloading but I cant figure out how to fix it.


----------



## Gibson56 (Dec 21, 2007)

I fixed my problem and in case anyone comes across the same problem I will tell you how I fixed it. The ostream operator already uses a template type in its basic function and since you cannot make a template of a template it was causing this error to pop up. Instead you need to add the actual amount instead of using a template.


----------

