Reputation: 3096
I know there's a swath of C++ template questions circulating on SO like:
However, I'm currently battling against irksome g++
errors:
In file included from LinkedList.cpp:1:0:
LinkedList.h:9:7: error: partial specialization 'class List<T>' does not specialize any template arguments
class List<T>;
^
LinkedList.h:15:51: error: expected class-name before '{' token
template <class T> class LinkedList : public List {
^
In file included from main.cpp:2:0:
LinkedList.h:9:7: error: partial specialization 'class List<T>' does not specialize any template arguments
class List<T>;
^
LinkedList.h:15:51: error: expected class-name before '{' token
template <class T> class LinkedList : public List {
My program is (for the sake of brevity) three files which include an "interface" List.h
and a header-implementation file combo for a Linked List. As the compile errors suggest, there's an issue when extending the List
interface in LinkedList.h
. I'm not really sure why these are happening. I've tried solving the issue by using a mix of things like:
template <class T>
friend class List<T>;
template<class T>
class List<T>;
and doing:
#include "List.h"
in both LinkedList.cpp
and LinkedList.h
Here's List.h
#ifndef __A2_LIST_H__
#define __A2_LIST_H__
/**
* A simple interface for creating new List classes.
* This was chosen to reduce coupling between objects.
*/
template <typename T> class List {
public:
virtual bool add(T data) = 0;
virtual void add(unsigned index, T data) = 0;
virtual void clear() = 0;
virtual bool contains(T data) = 0;
virtual T get(unsigned index) = 0;
virtual unsigned indexOf(T data) = 0;
virtual unsigned lastIndexOf(T data) = 0;
virtual bool remove(T data) = 0;
virtual T set(unsigned index, T data) = 0;
virtual unsigned int size() = 0;
virtual bool isEmpty() = 0;
};
#endif // __A2_LIST_H__
Here's LinkedList.h
#ifndef __A2_LINKEDLIST_H__
#define __A2_LINKEDLIST_H__
#include <cstddef>
#include "List.h"
template <class T>
class List<T>;
#if !defined(nullptr)
#define nullptr NULL
#endif
template <class T> class LinkedList : public List {
public:
LinkedList(unsigned capacity);
virtual bool add(T data);
virtual void add(unsigned index, T data);
virtual void clear();
virtual bool contains(T data);
virtual T get(unsigned index);
virtual unsigned indexOf(T data);
virtual unsigned lastIndexOf(T data);
virtual bool remove(T data);
virtual T set(unsigned index, T data);
virtual unsigned int size();
virtual bool isEmpty();
void addFirst(T data);
void addLast(T data);
unsigned find(T data);
protected:
class Node {
public:
Node(T data) {
this->data = data;
}
T data;
Node *next, *previous;
};
Node *head, *tail;
private:
unsigned capacity, _size;
LinkedList::Node* _seek(unsigned index);
};
#endif // __A2_LINKEDLIST_H__
and here's LinkedList.cpp
#include "LinkedList.h"
template <class T> LinkedList<T>::LinkedList(unsigned capacity) {
this->capacity = capacity;
this->_size = 0;
}
template <class T> bool LinkedList<T>::add(T data) {
this->addFirst(data);
return true;
}
template <class T> void LinkedList<T>::add(unsigned index, T data) {
if(index > this->capacity) {
throw "Index cannot be greater than the capacity";
}
static LinkedList<T>::Node *node = new LinkedList::Node(data);
if(index == 0 && this->_size == 0) { // adding to empty list
this->addFirst(data);
} else if(index == this->_size + 1) { // end of list
this->addLast(data);
} else { // somewhere in the middle
LinkedList<T>::Node *fNode = this->_seek(data);
if(fNode != NULL) {
// TODO: insert new node here
}
}
this->_size++;
}
template <class T> bool LinkedList<T>::isEmpty() {
return this->_size == 0;
}
template <class T> unsigned LinkedList<T>::size() {
return this->_size;
}
The thought process behind this is what I wanted to keep the coupling loose as a charge ahead on developing my application. Any advice on how to resolve this issue and why it's occurring is greatly appreciated. I am still very new to C++ so a lot of these issues are not-so-surprisingly cryptic.
Upvotes: 0
Views: 83
Reputation: 1868
In your LinkedList definition, try:
template <class T> class LinkedList : public List<T> { /*...*/ };
(note List<T>
instead of just List
)
There is also no need for the forward-declared template <class T> class List
portion in LinkedList.h, as you are including the full class declaration.
Another thing worth noting is that your template class implementation should be in the header file too, rather than in a separate LinkedList.cpp file. C++ cannot save binaries of template definitions, and they must be derived at compile time by being included in the headers. It has enough sense to ensure they are only defined once though, unlike defining a non-template (and non-inline) function implementation in the header.
Upvotes: 1
Reputation: 211
I believe that in template <class T> List<T>
you should remove the <T>
from the end of list, since you aren't specializing it, and I believe template <class T> class LinkedList : public List {
should be template <class T> class LinkedList : public List<T> {
Upvotes: 0