I'm trying to create a individual List with a templated value, but unfortunately I can not link from my List to the ListElements with templates.
In my main I call List<int> list1; to create a instance of the class List.
A List contains multiple ListElements that contain the value, that should be templated.
Compiler throws an error at
ListElement* first;
ListElement* last;
in List.h. It says C2955 - 'ListElement' : use of class type requires type argument list
List.h
#pragma once
#include <string>
#include "ListElement.h"
template<class T>
class List
{
private:
    ListElement* first;
    ListElement* last;
public:
    List();
    ~List();
    void printList();
    void pushBack(T value);
    void pushFront(T value);
};
List.cpp
#include <iostream>
#include "List.h"
template<class T>
List<T>::List()
{
    first = NULL;
    last = NULL;
}
template<class T>
List<T>::~List()
{
}
template<class T>
void List<T>::pushBack(T value)
{
    if (last)
    {
        ListElement* tmp = last;
        last = new ListElement(value);
        last->setPrev(tmp);
        tmp->setNext(last);
    }
    else
    {
        first = new ListElement(value);
        last = first;
    }
}
template<class T>
void List<T>::pushFront(T value)
{
    if (first)
    {
        ListElement* tmp = first;
        first = new ListElement(value);
        first->setNext(tmp);
        tmp->setPrev(first);
    }
    else
    {
        last = new ListElement(value);
        first = last;
    }
}
template<class T>
void List<T>::printList()
{
    if (first)
    {
        ListElement* tmp = first;
        while (tmp)
        {
            std::cout << tmp->getValue() << std::endl;
            if (tmp != last)
                tmp = tmp->getNext();
            else
                break;
        } 
    }
    else 
    {
        std::cout << "List is empty!" << std::endl;
    }
}
template class List<int>;
template class List<std::string>;
ListElement.h
#pragma once
#include <string>
template<class T>
class ListElement
{
private:
    ListElement* next;
    ListElement* prev;
    T value;
public:
    ListElement(T val);
    ~ListElement();
    ListElement* getNext() { return next; }
    ListElement* getPrev() { return prev; }
    void setNext(ListElement* elem) { next = elem; }
    void setPrev(ListElement* elem) { prev = elem; }
    T getValue() { return value; }
};
ListElement.cpp
#include "ListElement.h"
template<class T>
ListElement<T>::ListElement(T val)
{
    value = val;
}
template<class T>
ListElement<T>::~ListElement()
{
}
template class ListElement<int>;
template class ListElement<std::string>;
 
    