-1

Am new to template concept , and was trying to make a Generic Stack , and try balanced parenthesis problem on it. When tried to build the code, I am getting the error C2990 in Visual Studio 2010. The code is as under. Kindly suggest me a solution , as am stuck with this problem , and can't find a solution to it.

Extact Error :- error C2990: 'node' : non-class template has already been declared as a class template

template<class T>
struct node {
    T data;
    struct node * next;
};

template<class T>
class Stack {
    struct node *top;
public : 
    Stack() {
        top = NULL;
    }
    void push(T value);
    T pop();
    T peek();
    int isEmpty();
};

template<class T>
void Stack<T>::push(T value) {
    struct node *new_node = new node;
    if(new_node == NULL) {
        cout << "Stack Overflow" << endl;
        return;
    }
    new_node->data = value;

    if(top != NULL) {
        new_node->next = top;
        top = new_node;
    } else {
        top = new_node;
        new_node->next = NULL;
    }
}

template<class T>
T Stack<T>::pop() {
    if(top == NULL) {
        cout << "Stack Underflow" << endl;
        return ;
    }
    T value = top->data;
    struct node *tmp = top;
    top = top->next;
    free(tmp);
    return value;
}

template<class T>
T Stack<T>::peek() {
    if(top == NULL) {
        cout << "Stack Underflow" << endl;
        return ;
    }
    return top->data;
}

template<class T>
int Stack<T>::isEmpty() {
    if(top == NULL) 
        return TRUE;
    return FALSE;
}

int balanced(char a, char b) {
    switch(a) {
    case '[' : 
        if(b == ']')
            return TRUE;
        return FALSE;
    case '{' :
        if(b == '}')
            return TRUE;
        return FALSE;
    case '(' :
        if(b == ')')
            return TRUE;
        return FALSE;
    }
}

int isOpeningParenthesis(char a) {
    if(a == '[' || a == '{' || a == '(')
        return TRUE;
    return FALSE;
}

int isClosingParenthesis(char a) {
    if(a == ']' || a == '}' || a == ')')
        return TRUE;
    return FALSE;
}

int balancedParenthesis(char *arr, int length) {
    int i;
    Stack<char> *s = new Stack<char>;
    for(i=0; i<length; i++) {
        if(TRUE == isOpeningParenthesis(arr[i]))
            s->push(arr[i]);
        else if(TRUE == isClosingParenthesis(arr[i])){
            if((TRUE == s->isEmpty()) || (FALSE == balanced(s->pop(), arr[i])))
                return FALSE;
        }
    }
    if(FALSE == s->isEmpty())
        return FALSE;
    return TRUE;
}

int main() {
    char a1[10] = {'{','[',']','(','(',')',')','[',']','}'};
    char a2[5] = {'[','[',']',']','}'};

    for(int i = 0; i < 10; i++)
        cout << a1[i] << " ";
    cout << endl;
    if(TRUE == balancedParenthesis(a1, sizeof(a1)/sizeof(a1[0])))
        cout << "Balanced Parenthesis " << endl;
    else
        cout << "Not balanced parenthesis" << endl;

    for(int i = 0; i < 5; i++)
        cout << a2[i] << " ";
    cout << endl;
    if(TRUE == balancedParenthesis(a2, sizeof(a2)/sizeof(a2[0])))
        cout << "Balanced Parenthesis " << endl;
    else
        cout << "Not balanced parenthesis" << endl;

    getch();
    return 0;
}
Dovydas Šopa
  • 2,282
  • 8
  • 26
  • 34
  • And *where* do you get the error? Please indicate it in the code shown with e.g. a comment. – Some programmer dude Jan 26 '17 at 11:47
  • On a couple of unrelated notes, why are you using `int` and `TRUE` and `FALSE` when programming in C++? C++ have a native `bool` type that can be `true` or `false`. You also have a memory leak in your `balancedParenthesis` function. You don't to create objects with `new` in C++, declaring something as an ordinary variable works just as fine (so you could do e.g. `Stack s;`). Lastly, doing e.g. `return top == NULL` will work and return `true` if the expression is true, and `false` otherwise, no need for an `if`. – Some programmer dude Jan 26 '17 at 11:49
  • Why are you using `int` (`TRUE`, `FALSE`) instead of `bool`? – Simon Kraemer Jan 26 '17 at 11:50
  • 1
    Oh, and you allocate nodes with `new` but free them with `free()`. That won't work at all. And your `peek` and `pop` functions will not return a value at all in case of underflow of your stack, leading to *undefined behavior*. – Some programmer dude Jan 26 '17 at 11:52
  • 1
    `struct node * next;` That's not a valid syntax. You want to forward declare `node`. – Algirdas Preidžius Jan 26 '17 at 11:54
  • @AlgirdasPreidžius No that's one of the (few) working parts. The `node` symbol is declared by the initial `struct node` part when defining the structure. Also all mentions of `node` inside the structure implicitly means `node`. The `struct` keyword is not needed though, `struct` and `class` are quite similar that way. – Some programmer dude Jan 26 '17 at 11:55
  • @Someprogrammerdude In that case, I never seen lists implemented this way. I always seen them done with forward-declarations. – Algirdas Preidžius Jan 26 '17 at 11:56
  • @AlgirdasPreidžius That is the most basic, simplest and quintessential implementation of a single-linked list in both C and C++. – Some programmer dude Jan 26 '17 at 11:58
  • 3
    You're using `struct node` inside `Stack` where you probably meant `node`. – Angew is no longer proud of SO Jan 26 '17 at 11:58
  • I used TRUE & FALSE , as i love the concept of MACRO. I have on purpose removed those lines while commenting the code, as they don't hinder the logic much. As this was my first question ever, I will make a note for it next time. And yeah i do know about the memory leak, after this query of mine gets answered i will try adding the Smart Pointer Class concept and try again. – user2365713 Jan 26 '17 at 11:59
  • Templates are not something you can easily learn by trial & error. You would benefit from following a [good book](http://stackoverflow.com/q/388242/1782465). – Angew is no longer proud of SO Jan 26 '17 at 12:00
  • I appreciate you prompt responses to my query. – user2365713 Jan 26 '17 at 12:00
  • Can someone find something relevant from the below link and help me out in the similar problem am facing. Link : http://stackoverflow.com/questions/5995774/forward-declared-type-and-non-class-type-as-already-been-declared-as-a-class-ty – user2365713 Jan 26 '17 at 12:04
  • 1
    @user2365713 preprocessor macros is something that C++ community typically trying to get rid of. Stop loving them. Begin learning C++ by forgetting everything you know about C, upgrading your compiler and getting a good book. – Ivan Aksamentov - Drop Jan 26 '17 at 12:04
  • @Someprogrammerdude This is the exact line where am getting the above mentioned error. struct node *top; – user2365713 Jan 26 '17 at 12:10
  • @Drop : Thanks for the advice, I refrain myself from using the macros in C++, anymore. Guys, if you have more insight on the above code of mine, kindly share it. It will eventually improve my coding, thanks in advance. And for the problem statement, if someone is aware of a solution kindly suggest the same. – user2365713 Jan 26 '17 at 12:10
  • @user2365713 Comment by Angew above most likely solves your problem. Read carefully. If not, you should let us know that you tried it and it didn't help. In short: do not append `struct` keyword when using a type. It is not necesary in C++ as there is no tag namespace. – Ivan Aksamentov - Drop Jan 26 '17 at 12:13
  • The line you say have the error should not have the error unless there is a bug in the old Visual C++ 2010 compiler. You say the code you show is not the actual code you have? Then maybe you have edited it so the error no longer exist. Please try to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) which *have* the error. – Some programmer dude Jan 26 '17 at 12:14
  • @Someprogrammerdude The only code i removed was as under :- #include #include using namespace std; #define TRUE 1 #define FALSE 0 And rest code is same.. I will with some smaller problem. – user2365713 Jan 26 '17 at 12:21
  • [mcve] please! I bet most of your code is not relevant for the question. – Werner Henze Jan 27 '17 at 09:59

1 Answers1

0

In the code:

template<class T>
class Stack {
    struct node *top;

it should be:

template<class T>
class Stack {
    node<T> *top;

It is good style to avoid repeating the keyword struct where it is not necessary. You make this same error again later in the code. Also your code has various other errors, but this particular one was the cause of your error message.

NB. In future don't post irrelevant code in the question, and indicate which line the error message occurred on.

M.M
  • 138,810
  • 21
  • 208
  • 365