Problems linking template linked list class

I'm writing a linked list class for my computer science class and everything works except I keep getting this error.
"Main.obj : error LNK2019: 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 LinkList<char> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$LinkList@D@@@Z) referenced in function _main
Main.obj : error LNK2019: 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 LinkList<int> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$LinkList@H@@@Z) referenced in function _main"

This is the class named "LinkList.h"
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
#include <ostream>
using namespace std;

template <typename T>
class LinkList
{ private:
  class Node
  {
   public:
    T info;
    Node *next;
  };
  typedef Node *nodePtr;
 
 public:
  	LinkList();			//constructor 
	LinkList(const LinkList<T> & orig);	//copy constructor
	~LinkList();		//destructor
	bool empty();		//determine if the LinkList is empty
	T Front();			// returns item at front of LinkList
	T Back();			// returns item at back of LinkList
	void Push_back(const T & item);
// add an item at the end of the LinkList
	void Push_front(const T & item);
//add item at the begining of LinkList
	void pop_back();	//remove the last item of the LinkList
	void pop_front();	//remove the first item of the LinkList
	void insert(T item);
						//insert the item in ascending order
	void erase(T item);
						//remove the item in the list
	bool Search(T item);
						//search a given item, if it can be found, 
						//return true, otherwise return false
	int Count();		//return the number of items in the list
	LinkList<T>& operator=(const LinkList<T> & orig);
								//overloaded assignment operator
	friend ostream& operator<<(ostream &out, const LinkList<T> & L);
								//overloaded output operator 

  private:
      nodePtr First;		//node pointer which points to the front(first node)
};  

template<typename T>
LinkList<T>::LinkList()
{
	First = 0;
}
template<typename T>
LinkList<T>::LinkList(const LinkList<T> &orig)
{
	if(orig.First != 0)
	{
		First->info = orig.First->info;
		nodePtr temp, cursor;
		cursor = orig.First->next;
		temp = new Node;
		temp = First->next;
		while(cursor != 0)
		{
			temp->info = cursor->info;
			cursor = cursor->next;
			temp->next = new node;
			temp = temp->next;
		}
	}
	else
		cerr << "List is empty!";
}
template <typename T>
LinkList<T>::~LinkList()
{
	nodePtr cursor = First;
	while(cursor !=0)
	{
		First = First->next;
		delete cursor;
		cursor = First;
	}
}
template <typename T>
bool LinkList<T>::empty()
{
	return (First == 0);
}
template <typename T>
T LinkList<T>::Front()
{
	if(!empty())
		return First->info;
	else
		cerr << "List is empty!";
}
template <typename T>
T LinkList<T>::Back()
{
	nodePtr cursor = First;
	if(empty())
		cerr << "List is empty!";
	while(cursor->next != 0)
		cursor = cursor->next;
	return cursor->info;
}
template <typename T>
void LinkList<T>::Push_back(const T &item)
{
	nodePtr cursor = First;
	while(cursor->next != 0)
		cursor = cursor->next;
	cursor->next = new Node;
	cursor = cursor->next;
	cursor->info = item;
}
template <typename T>
void LinkList<T>::Push_front(const T &item)
{
	nodePtr cursor = new Node;
	cursor->info = item;
	cursor->next = First;
	First = cursor;
}
template <typename T>
void LinkList<T>::pop_back()
{
	nodePtr cursor = First;
	nodePtr preCursor = First;
	while(cursor->next != 0)
	{
		preCursor = cursor;
		cursor = cursor->next;
	}
	delete cursor;
	preCursor->next = 0;
}
template <typename T>
void LinkList<T>::pop_front()
{
	nodePtr cursor = First;
	First = First->next;
	delete cursor;
}
template <typename T>
void LinkList<T>::insert(T item)
{
	nodePtr cursor = First;
	while(cursor->next != 0 && cursor != 0)
	{
		if(cursor->info <= item)
			cursor = cursor->next;
		else
		{
			cursor->next = new node;
			cursor = cursor->next;
			cursor->info = item;
		}
	}
}
template <typename T>
void LinkList<T>::erase(T item)
{
	nodePtr cursor = First;
	if(!empty())
	{
		while(cursor->info != item)
			cursor = cursor->next;
		delete cursor;
	}
	else
		cerr << "List is empty!";
}
template <typename T>
bool LinkList<T>::Search(T item)
{
	nodePtr cursor = First;
	while(cursor->info != item && cursor != 0)
		cursor = cursor->next;
	return (cursor->info == item);
}
template <typename T>
int LinkList<T>::Count()
{
	nodePtr cursor = First;
	int count;
	if(!empty())
	{
		for(count = 1; cursor != 0; count++)
			cursor = cursor->next;
	}
	else
		count = 0;
	return count;
}
template <typename T>
LinkList<T>& LinkList<T>::operator=(const LinkList<T> & orig)
{
	nodePtr cursor = First;
	if(!orig.empty())
	{
		while(cursor != 0)
		{
			delete cursor;
			cursor = cursor->next;
		}
		cursor = First;
		nodePtr cursor2 = orig.First;
		while(cursor2 != 0)
		{
			cursor = new node;
			cursor->info = cursor2->info;
			cursor->next = cursor2->next;
			cursor2 = cursor2->next;
			cursor = cursor->next;
		}
	}
	else
		cerr << "Empty list cannot be copied!";
	return (*this);
}
template <typename T>
ostream& operator<<(ostream &out, const LinkList<T> &L)
{
	nodePtr cursor = L.First;
	if(!L.empty())
	{
		while(cursor != 0)
		{
			out << cursor->info << "\t";
			cursor = cursor->next;
		}
		out << endl;
		return out;
	}
	else
		out << "List is empty" << endl;
};

The driver program is "Main.cpp"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include "LinkList.h"
using namespace std;

int main()
{
	LinkList<int> intList;
	LinkList<char> charList;
	intList.Push_back(14);
	charList.Push_front('f');
	cout << intList;
	cout << charList;
        return 0;
} 

I've tried about everything to fix it. Any suggestions?
You need template <typename T> in before declaration of friend ostream
I put that before the declaration and it stopped recognizing the class objects inside the function definition. I just moved the definition into the class without the template header and now it's working for some reason but thanks for the help anyways.
I put that before the declaration and it stopped recognizing the class objects inside the function definition

change nodePtr cursor = L.First; to LinkList<T>::nodePtr cursor = L.First;
I ran your code and got several errors I had to fix to get it working. I would add a Node ctor and a check in push_back to see if First is a used node.
Topic archived. No new replies allowed.