0

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>;
Colin Rauch
  • 515
  • 1
  • 6
  • 17

1 Answers1

2

ListElement is a template, so you want to use a specific instantiation for your pointers:

template<class T>
class List
{
private:
    ListElement<T>* first;
    ListElement<T>* last;
    // note:   ^^^

likewise for other occurrences. Only within the template, the template name is usable for the current instantiation, i.e., within List, you can use List as a shortcut for List<T>.

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180