I have the following classes, SLList, an integer datatype-based linked list and DLList, a template-based linked list. My problem is that SLList is working perfectly, but as soon as i modify it to be used as a template, i get errors, more specifically LNK 2019, i.e. linking errors. I avoided the use of pointers and have been up all night trying to fix it. Please help:

SLList.h:

```
#ifndef SLLIST_H
#define SLLIST_H
#include <iostream>
using namespace std;
class ListNode
{
public:
int data;
ListNode *next;
ListNode *previous;
ListNode(){next = previous = NULL;}
ListNode(int d, ListNode *p = NULL, ListNode *n = NULL)
{
data = d;
previous = p;
next = n;
}
};
class SLList
{
private:
ListNode *head, *tail;
int length;
public:
SLList();
~SLList();
bool isEmpty();
bool isInlist(int data);
void addToHead(int data);
void addToTail(int data);
int removeTail();
int removeHead();
bool deleteData(int data);
void clearList();
friend ostream &operator<<(ostream &os, SLList& list);
};
#endif
```

SLList.cpp:

```
#include "SLList.h"
using namespace std;
SLList::SLList()
{
tail = head = NULL;
}
SLList::~SLList()
{
while(!isEmpty())
removeTail();
}
bool SLList::isEmpty()
{
if(this->head == NULL)
return true;
else
return false;
//return (head == NULL) ? true : false;
}
bool SLList::isInlist(int data)
{
ListNode *temp = head;
while(temp != NULL && temp->data != data)
temp = temp->next;
return (temp == NULL) ? false : true;
}
void SLList::addToHead(int data)
{
head = new ListNode(data, NULL, head);
if(tail == NULL)
tail = head;
else
head->next->previous = head;
}
void SLList::addToTail(int data)
{
if(isEmpty())
head = tail = new ListNode(data);
else{
tail->next = new ListNode(data, tail);
tail->next->previous = tail;
tail = tail->next;
}
}
int SLList::removeHead(){
if(!isEmpty())
{
ListNode *temp = head;
int tempData = temp->data;
if(head == tail)
head = tail = NULL;
else {
head = head->next;
head->previous = NULL;
}
delete temp;
return tempData;
} else
exit(1);
}
int SLList::removeTail(){
if(!isEmpty()){
int tempData = tail->data;
if(tail != head){
ListNode *temp = tail;
tail = tail->previous;
tail->next = NULL;
delete temp;
} else {
delete tail;
head = tail = NULL;
}
return tempData;
} else
exit(1);
}
bool SLList::deleteData(int data)
{
ListNode *temp = head;
while(temp != NULL && temp->data != data)
temp = temp->next;
if(temp == NULL)
return false;
else{
temp->previous->next = temp->next;
temp->next->previous = temp->previous;
delete temp;
return true;
}
}
void SLList::clearList(){
while(!isEmpty())
removeTail();
}
ostream& operator<<(ostream &os, SLList& l)
{
if(!l.isEmpty())
{
ListNode *temp = l.head;
for(int i = 1; temp != NULL; i++)
{
os << i << ".\t" << temp->data << endl;
temp = temp->next;
}
} else
os << "No data in list." << endl;
return os;
}
```

DLList.h:

```
#ifndef DLLIST_H
#define DLLIST_H
#include <iostream>
using namespace std;
template <class T>
class ListNode
{
T data;
ListNode *next;
ListNode *previous;
ListNode(){next = previous = NULL;}
ListNode(T d, ListNode *p = NULL, ListNode *n = NULL)
{
data = d;
previous = p;
next = n;
}
};
template <class T>
class DLList
{
private:
ListNode<T> *head, *tail;
int length;
public:
DLList();
~DLList();
bool isEmpty();
bool isInlist(T data);
void addToHead(T data);
void addToTail(T data);
T removeTail();
T removeHead();
bool deleteData(T data);
void clearList();
friend ostream &operator<<(ostream &os, DLList<T>& list);
};
#endif
```

DLList.cpp:

```
#include "DLList.h"
using namespace std;
template <class T>
DLList<T>::DLList()
{
tail = head = NULL;
}
template <class T>
DLList<T>::~DLList()
{
while(!isEmpty())
removeTail();
}
template <class T>
bool DLList<T>::isEmpty()
{
if(this->head == NULL)
return true;
else
return false;
}
template <class T>
bool DLList<T>::isInlist(T data)
{
ListNode<T> *temp = head;
while(temp != NULL && temp->data != data)
temp = temp->next;
if(temp == NULL)
return false;
else
return true;
}
template <class T>
void DLList<T>::addToHead(T data)
{
head = new ListNode<T>(data, NULL, head);
if(tail == NULL)
tail = head;
else
head->next->previous = head;
}
template <class T>
void DLList<T>::addToTail(T data)
{
if(isEmpty())
head = tail = new ListNode<T>(data);
else{
tail->next = new ListNode<T>(data, tail);
tail->next->previous = tail;
tail = tail->next;
}
}
template <class T>
T DLList<T>::removeHead(){
if(!isEmpty())
{
ListNode<T> *temp = head;
T tempData = temp->data;
if(head == tail)
head = tail = NULL;
else {
head = head->next;
head->previous = NULL;
}
delete temp;
return tempData;
} else
exit(1);
}
template <class T>
T DLList<T>::removeTail(){
if(!isEmpty()){
T tempData = tail->data;
if(tail != head){
ListNode<T> *temp = tail;
tail = tail->previous;
tail->next = NULL;
delete temp;
} else {
delete tail;
head = tail = NULL;
}
return tempData;
} else
exit(1);
}
template <class T>
bool DLList<T>::deleteData(T data)
{
ListNode<T> *temp = head;
while(temp != NULL && temp->data != data)
temp = temp->next;
if(temp == NULL)
return false;
else{
temp->previous->next = temp->next;
temp->next->previous = temp->previous;
delete temp;
return true;
}
}
template <class T>
void DLList<T>::clearList(){
while(!isEmpty())
removeTail();
}
template <class T>
ostream& operator<<(ostream &os, DLList<T>& l)
{
if(!l.isEmpty())
{
ListNode<T> *temp = l.head;
for(int i = 1; temp != NULL; i++)
{
os << i << ".\t" << temp->data << endl;
temp = temp->next;
}
} else
os << "No data in list." << endl;
return os;
}
```

app.cpp

```
#include "DLList.h" //replace with SLList
using namespace std;
int main()
{
typedef DLList<int> List; //replace with typedef SLList List;
List intList;
intList.addToHead(1);
intList.addToHead(3);
intList.addToHead(7);
intList.addToHead(9);
intList.addToHead(11);
intList.addToHead(4);
intList.addToHead(12);
intList.addToHead(54);
intList.addToHead(67);
intList.deleteData(3);
cout << intList;
return 0;
}
```

the exact errors is 'Error 1 error LNK2019: unresolved external symbol' for every function declared in main.