Reputation: 17
I'm trying to add a nested struct (Node) that takes the same template param 'T' passed into the baseclass (LinkedList).
When I try to template the outer LinkedList class, I get a "explicit specialization of non-template class LinkedList" error. If I don't add it, the private Nodes "head" and "tail" don't recognize 'T'
When I add the template to the Node class, I get a "Declaration of 'T' shadows template parameter" error. However, if I don't add it explicitly to the Node class, the 'T' is not recognized at all in the struct.
How do I declare template and pass it correctly from the LinkedList class to the nested, private Node struct correctly?
template<class T>
class LinkedList<T> {
private:
template<typename T>
struct Node {
T value;
Node<T>* next;
Node<T>* previous;
Node<T>(T value, Node<T>* next, Node<T>* previous)
:value(value),
next(next),
previous(previous){}
Node<T>& operator=(const Node<T>&) = delete;
};
Node<T>* head;
Node<T>* tail;
LinkedList& operator=(const LinkedList&) = delete;
public:
LinkedList<T>()
:head(nullptr),
tail(nullptr){}
~LinkedList<T>();
LinkedList& insertTail(T value);
};
Upvotes: 1
Views: 855
Reputation: 66194
Lose all the extraneous <T>
madness and simply used the outer template parameter. It is perfectly legal to do so:
template<class T>
class LinkedList
{
private:
struct Node {
T value;
Node* next;
Node* previous;
Node(T value, Node* next, Node* previous)
: value(value), next(next), previous(previous)
{}
Node& operator=(const Node&) = delete;
};
Node* head;
Node* tail;
LinkedList& operator=(const LinkedList&) = delete;
public:
LinkedList()
: head(nullptr)
, tail(nullptr)
{}
~LinkedList();
LinkedList& insertTail(T value);
};
Related: My crystal ball tells me you should read this before implementing the rest of the functions that are only declared here.
Best of luck.
Upvotes: 3
Reputation: 137310
When declaring a primary template (i.e., not a specialization), don't add <T>
after the name:
template<class T>
class LinkedList {
Node
shouldn't be a template; for any particular T
, a LinkedList<T>
should only have one type of Node
s - those that hold T
:
struct Node {
T value;
Node* next;
// ...
};
Finally, the <T>
is implied when you write the template's name in its definition, so you don't need to explicitly specify it:
LinkedList()
:head(nullptr),
tail(nullptr){}
~LinkedList();
Upvotes: 2