Список, що приймає різні типи даних

#include <iostream>
#include <string>

template <class K>
class Node
{
     K _data;
     Node* next;

public:

     Node() { }

     Node(K d) {
          _data = d;
          next = nullptr;
     }

     void setNext(Node* n) {
          next = n;
     }

     void setData(K val) {
          _data = val;
     }

     K getData() {
          return _data;
     }

     Node* getNext()
     {
          return next;
     }

     ~Node() { }
};


template <class T>
class List
{
     Node<T>* head;
     Node<T>* tail;
     int size;

public:

     List()
     {
          head = tail = nullptr;
          size = 0;
     }

     void PushBack(T val) {
          Node<T>* tmp = new Node<T>(val);
          if (size == 0)
          {
               head = tail = tmp;
               size = 1;
          }
          else {
               tail->setNext(tmp);
               tail = tmp;
               size++;
          }
     }

     T PopStart() {
          T d;
          if (size>0)
          {
               if (size == 1) {
                    d = head->getData();
                    delete head;
                    head = nullptr;
                    tail = nullptr;
                    size = 0;
               }
               else
               {
                    d = head->getData();
                    Node<T>* tmp = head;
                    head = head->getNext();
                    delete tmp;
                    size--;
               }
          }
          return d;
     }


     T PopBack() {
          T d;
          if (size>0)
          {
               if (size == 1) {
                    d = head->getData();
                    delete head;
                    head = nullptr;
                    tail = nullptr;
                    size = 0;
               }
               else
               {
                    d = tail->getData();
                    Node<T>* prev = head;
                    Node<T>* tmp = head;
                    Node<T>* next = head;
                    while (next != nullptr) {
                         prev = tmp;
                         tmp = next;
                         next = next->getNext();
                    }
                    delete tmp;
                    tail = prev;
                    tail->setNext(nullptr);
                    size--;
               }
          }

          return d;
     }

     void Show() {
Node<T>* cur = head;
while (cur) {
cout << cur->getData() << " ";
cur = cur->getNext();
}
     }


     ~List() { }
};


int main() {

     List<int> A;

     A.PushBack(3);
     A.PushBack(4);
     A.PushBack(5);

     cout << "Queque:" << endl;
     cout << A.PopStart() << endl;
     cout << A.PopStart() << endl;
     cout << A.PopStart() << endl;

     A.PushBack(3);
     A.PushBack(4);
     A.PushBack(5);

     cout << endl << "Stack:" << endl;
     cout << A.PopBack() << endl;
     cout << A.PopBack() << endl;
     cout << A.PopBack() << endl;

     cout << endl;
     List<string> B;

     B.PushBack("AA");
     B.PushBack("BB");
     B.PushBack("CC");

     cout << "Queque:" << endl;
     cout << B.PopStart()<<endl;
     cout << B.PopStart() << endl;
     cout << B.PopStart() << endl;

     B.PushBack("AA");
     B.PushBack("BB");
     B.PushBack("CC");

     cout << endl << "Stack:" << endl;
     cout << B.PopBack() << endl;
     cout << B.PopBack() << endl;
     cout << B.PopBack() << endl;

     system("pause");
     return 0;
}



Queque:
3
4
5

Stack:
5
4
3

Queque:
AA
BB
CC

Stack:
CC
BB
AA