1

I am working on recreating the forward linked list class so I can better understand pointers. I have hit a roadblock, I have a template class called forward_list. Within this class in the private section I have another class which I want to have the same type as the main (external) class, this class is called node.

#ifndef FORWARD_LIST_HPP
#define FORWARD_LIST_HPP

template <class T>
class forward_list
{
    private:
        class node
        {
            T data;
            node<T>* next;
        };
        node<T>* head, tail;
    public:
        forward_list();
        ~forward_list();
        void pushBack(T t);
        void print();
};

#endif

When I compile the above code with the rest of my code I produce this error:

./forward_list.hpp:11:19: error: non-template type ‘node’ used as a template
   11 |             node<T>* next;
      |  

I also have tried this (I will add a '*' on the line I have added.)

#ifndef FORWARD_LIST_HPP
#define FORWARD_LIST_HPP

template <class T>
class forward_list
{
    private:
        template <class T>   // *
        class node
        {
            T data;
            node<T>* next;
        };
        node<T>* head, tail;
    public:
        forward_list();
        ~forward_list();
        void pushBack(T t);
        void print();
};

#endif

Here is the error this change has produced:

./forward_list.hpp:8:19: error: declaration of template parameter ‘T’ shadows template parameter
    8 |         template <class T>
      | 
Breadleaf
  • 161
  • 4
  • 4
    Use simply `node`. See [class name injection](https://en.cppreference.com/w/cpp/language/injected-class-name). – YSC Apr 05 '22 at 20:40
  • You know you can give template parameters names other than `T`, yes? – Taekahn Apr 05 '22 at 20:45
  • @YSC I found that article really dense :/ are you implying that the use of ```template ``` is not needed above the class node? If that is what you are saying, how do I handle the errors? Could it be something else in my code? – Breadleaf Apr 05 '22 at 20:49
  • @Taekahn Yes I do but I want the node to have the same type as the overall class called `forward_list` so that I can make the class overall work as a template. – Breadleaf Apr 05 '22 at 20:50
  • @Breadleaf It will, if you do it right. Separate (for illustrative purposes ) the two classes. Get them to compile. Change up the template parameters names (to foo and bar, respectively) then combine the classes again and see what you get. – Taekahn Apr 05 '22 at 20:52

2 Answers2

5

Your first example is pretty close to what you want. The thing to realize is that while forward_list is a class template, forward_list<T> is a class, and forward_list<T>::node is also a class, not a class template. But also forward_list<int>::node is a totally separate class from forward_list<double>::node, even though they're both just called node.

So, the following would work:

template <class T>
class forward_list
{
    private:
        class node
        {
            T data;
            node* next; // Just node*, not node<T>*
        };
        node* head, tail; // Just node*, not node<T>*
    public:
        forward_list();
        ~forward_list();
        void pushBack(T t);
        void print();
};

This way forward_list<int> will have a nested class forward_list<int>::node with an int data; member variable, and forward_list<double> will have a nested class forward_list<double>::node with a double data; member variable.

Nathan Pierson
  • 5,461
  • 1
  • 12
  • 30
2

In the first case, the node is forward_list<T>::node, or just node within the list. There is no node<T>.

In the second case, the problem is that you have two templates both named T when you probably wanted two different templates.

So give them different names. :-)

template <class T>
class forward_list
{
        template <class U> 
        class node
        {
        };
};
BoP
  • 2,310
  • 1
  • 15
  • 24
  • 1
    I think the better solution is to drop the `` instead of adding a `template `, since there's no reason for `U` to be different from `T` anyway. – Nathan Pierson Apr 05 '22 at 20:57
  • Possibly (or likely :-). I'm just trying to explain why the compiler doesn't like the code. Not if it is a useful design... – BoP Apr 05 '22 at 20:59