0

I am very new to C++ template, and learning it through small programming.
I'm definitely not understanding what is wrong -- at all.
Here is the code.

Reverse a linked List using a stack

using namespace std;
template<typename T>
void Reverse( node<T> *front);
template<typename T>
void Display( node<T> *front);
template<typename T>
class node
{
public:
    T data;
    node<T> *next;
    node(){ next = NULL; }
    node(const T& item, node<T> *nextnode = NULL )
    {
        data = item;
        next = nextnode;
    }
};

int main()
{
    node<int> *front = NULL;
    int size, no;
    cout << "Enter the size of list ";
    cin >> size;
    for (int i = 1; i < size; i++)
    {
        cout << "Enter the " << i << " element " << endl;
        cin >> no;
        front = new node<int> ( no , front);
    }
    Reverse(front);
    Display(front);
    _getch();
    return 0;
}
template<typename T>
void Reverse(node<T> *front)
{
    node<T> *temp = front;
    stack<T> s;
    while (temp != NULL)
    {
        s.push(temp);        // Pushing the address into stack
        temp = temp->next;
    }
    temp = s.top();
    front = temp;
    s.pop();
    while (!s.empty())
    {
        temp->next = s.top();  // Popping the address from stack.
        s.pop();
        temp = temp->next;
    }
temp->next = NULL;
}

template<typename T>
void Display( node<T> *front)
{
    node<T> *temp = front;
    while (temp != NULL)
    {
        cout << temp->data << "  ";
        temp = temp->next;
    }
    cout << endl;
}

I am getting following both errors ( errors 1 & 2 ) for both functions ( i.e. Reverse() and Display() )
Error 1 ) error C2182: 'Reverse' : illegal use of type 'void'

Error 2) error C2998: 'int Reverse' : cannot be a template definition

Error 3) error C1903: unable to recover from previous error(s); stopping compilation.

I've tried every single thing I can think of. But could not succeed.

Barry
  • 286,269
  • 29
  • 621
  • 977
Tushar
  • 97
  • 4
  • 11

2 Answers2

1

I agree the error message is not super helpful in this case. The problem is what when the compiler sees

template<typename T>
void Reverse( node<T> *front);

it doesn't yet know what node<T> is. That class template isn't declared until after Reverse is declared. You can fix this by simply either moving both function template declarations (Reverse and Display) after the class template declaration for node<T>.

Alternatively, you could forward-declare node by just sticking template <typename T> class node; in front of the two function templates - but there's no reason for the forward declaration here.


Once the Reverse and Display declarations know what node<T> is, both of those are fine and you're left with the next error:

node<T> *temp = front;
stack<T> s;
s.push(temp);

s is a stack<T> - you can only push Ts onto it, but you're trying to push a node<T>*. Make sure you give the class template the type you're actually using it with:

stack<node<T>*> s;
Barry
  • 286,269
  • 29
  • 621
  • 977
  • @ Barry : I changed the order. (by putting Reverse() and Display() after class template declaration for node and before int main(). But surprisingly I got more errors along with previous. – Tushar May 10 '16 at 13:18
  • Error 5) C2365: 'Display' : redefinition; previous definition was 'data variable'
    Error 6) C2904: 'Display' : name already used for a template in the current scope
    – Tushar May 10 '16 at 13:20
  • Error 7) C2064: term does not evaluate to a function taking 1 arguments. All these 3 errors are for Reverse() also. – Tushar May 10 '16 at 13:23
  • All errors have been solved. Thanks for your help. But output is not proper. Can you help me in correcting logic ?? – Tushar May 11 '16 at 06:42
  • 1
    @Tushar. No. One question per question. If this answer helped you solve your problem, you should accept it. – Barry May 11 '16 at 10:37
-1

There are multiple problems with the shown code.

using namespace std;

This is considered to be a bad programming practice.

template<typename T>
void Reverse( node<T> *front);

The template node is not declared at this point. Your C++ code is compiled in order, from the beginning of the file to the end. At this point, the node template is not defined.

template<typename T>
void Reverse(node<T> *front)
{
    // ...

This template function is defined after main(), which uses it.

Templates must be defined before they are used. Again, your C++ code gets compiled in order, from the beginning of the file to the end. Template classes and functions must be defined before they are used.

Forward declarations work with ordinary classes and functions only. Although templates can also be forward-declared, it doesn't work the way you think it works. So, until you become more familiar with templates, and how they work, you should avoid forward-declaring any templates.

Community
  • 1
  • 1
Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • 3
    "*Although templates can also be forward-declared, it doesn't work the way you think it works."*, namely ? – Piotr Skotnicki May 10 '16 at 12:30
  • 3
    once a forward declaration is added, the code should more-or-less compile, what do you mean by *"Forward declarations work with ordinary classes and functions only."* ? – Piotr Skotnicki May 10 '16 at 12:34
  • 3
    _"So, until you become more familiar with templates, and how they work, you should avoid forward-declaring any templates."_ Sam, until you become more familiar with templates, and how they work, you should avoid teaching anything about templates. http://coliru.stacked-crooked.com/a/452597926b93d735 – Lightness Races in Orbit May 11 '16 at 10:50