c++templatesvisual-studio-2010stack

C++ add value into stack subscript requires array or pointer type and warning


I'm new to programming in C++. Also new to implementing stacks. My objective is creating RPN Calculator using template stack. Cant use the built in stack classes.

I have everything so far and now I am stuck, I can't think of how to fix this problem. I am currently getting these errors:

Error   C2109   subscript requires array or pointer type
Warning C4244   'return': conversion from 'double' to 'int', possible loss of data

This is my stack class:

    #include<stack>
#define STACK_MAX 500

template<class T>
class RPNCalculator
{
private:
    //Insanciating stack class
    T data[STACK_MAX];
    int size;

    //stack<T> rpnstack;


public:
    RPNCalculator() {
        size = 0;
    }

    ~RPNCalculator();

    int Top() {

        if (size == 0) {
            fprintf(stderr, "Error: stack empty\n");
            return -1;
        }
        return data[size - 1];
    }

    void push(T data); // pushes a new operand onto the stack
                          // the following operations are to be performed as defined for Reverse Polish Notation
                          // binary operators:
    T value();    // returns the topmost value
    void pop();     // returns the topmost value and pops it off the top

    double add();
    double subtract();
    double multiply();
    double divide();
    // unary operators:
    double square(); // squares the current value
    double negate(); // negates, i.e. 3 becomes -3
    bool isEmpty(); // tests to see if there are elements on the stack
    void clear(); // clears out the stack



};

template<class T>
inline bool RPNCalculator<T>::isEmpty()
{
    bool status;

    if (!top)
        status = true;
    else
        status = false;

    return status;
}

template<class T>
 void RPNCalculator<T>::clear()
{

}

 template<class T>
 inline RPNCalculator<T>::~RPNCalculator()
 {
 }

 template<class T>
 inline void RPNCalculator<T>::push(T data)
 {
     if (size < STACK_MAX)
         data[size++] = data;
     else
         fprintf(stderr, "Error: stack full\n");

 }

 template<class T>
inline T RPNCalculator<T>::value()
{
    return T();
}

template<class T>
 inline void RPNCalculator<T>::pop()
{
     if (size == 0)
         fprintf(stderr, "Error: stack empty\n");
     else
         size--;
 }

This is my main class:

    #include <iostream>
#include "RPNCalculator.h"
#include <string>
#include <sstream>

using namespace std;


bool isOperator(const string& input);
void performOperation(const string& st, RPNCalculator<double>& rpnstack);

int main() {
    cout << "Welcome to the RPN Calculator by AbdulFatai Saliu __D00168401" << endl;
    cout << "Enter c to clear \n"
         << "s to square \n"
         << "n to negate \n"
         << "p to pop current value \n"
         << "q to quit \n"
         ;

    RPNCalculator<double> rnpstack;

    string input;
    while (true) {

        //Dispaly prompt
        cout << ">> ";


        //get user input
        cin >> input;


        //check for numeric values
        double numereric;
        if (istringstream(input) >> numereric) {

        }
        else if (isOperator(input)) {

        }
        else if (input == "q") {
            return 0;
        }
        else {
            cout << "Input Not Valid" << endl;
        }
        //check for operators 

        //check for exit 

        // display invalid value message
    }


    system("PAUSE");

    //return 0;
}

bool isOperator(const string& input) {
    string operators[] = { "-","+","*","/"};

    for (int i = 0; i < 6; i++) {
        if (input == operators[i]) {
            return true;
        }
    }

    return false;
}

void performOperation(const string& input, RPNCalculator<double>& rpnstack) {
    double firstValue, secondValue, result;

    firstValue = rpnstack.Top();
    rpnstack.pop();
    secondValue = rpnstack.Top();
    rpnstack.pop();

    if (input == "-") {
        result = secondValue - firstValue;
    }
    else if (input == "+") {
        result = secondValue + firstValue;
    }
    else if (input == "*") {
        result = secondValue * firstValue;
    }
    else if (input == "/") {
        result = secondValue / firstValue;
    }

    cout << result << endl;

    rpnstack.push(result);


}

the problem seems to be coming from my push() method in the RPNCalculator template class.


Solution

  • Looks like you have a parameter for the function void push(T data); where the parameter has the same name as the class member (data, your storage). Try changing the parameter name in the function implementation that doesn't yield this conflict. You could also be specific which data you want to use if you really want to use that name.

    Try this one instead

     template<class T>
     inline void RPNCalculator<T>::push(T arg)
     {
         if (size < STACK_MAX)
             data[size++] = arg;
         else
             fprintf(stderr, "Error: stack full\n");
    
     }
    

    or, if you want to be explicit about which data you are assigning

     template<class T>
     inline void RPNCalculator<T>::push(T data)
     {
         if (size < STACK_MAX)
             this->data[size++] = data; // this->data is the member, data is the function local variable
         else
             fprintf(stderr, "Error: stack full\n");
    
     }
    

    This is usually avoided by naming the member variables in a way where there can't be conflicts. One way is to prefix your members with m_, where data would become m_data. Feel free to use any style of code that you want, but I'd suggest avoiding conflicts (and the second approach) when possible.