Trying to access an index of an std::stack

13,188

Solution 1

std::stack doesn't inherit from the underlying container type, it adapts it to a completely new interface. The underlying container is not exposed. That's essentially the point of the adaptors std::stack and std::queue: they ensure that you're using a more limited interface that will be the same regardless of the underlying structures.

That said, you can inherit from std::stack and access the underlying container from a subclass. It is a protected member named c.

class my_stack : public std::stack< char > {
public:
    using std::stack<char>::c; // expose the container
};

int main() {
    my_stack blah;
    blah.push( 'a' );
    blah.push( 'b' );
    std::cout << blah.c[ 1 ]; 
}

http://ideone.com/2LHlC7

Solution 2

You should use the .top() method to check what's on top of the stack, not indexing.


Thus, instead of your current code …

if(!stack[j]){//since j-1 when the index is 0 will cause an error
  if(stack[j-1]==matchingBracket){
    stack.pop();
  }else{
    stack.push(input);
  }
}

write

if(!stack.empty() && stack.top() == matchingBracket) {
    stack.pop();
} else {
    stack.push(input);
}

Solution 3

Stack doesn't support random access to its elements by definition. See std::stack reference.

Actually in your case container choice is wrong. If you need to access elements randomly (not only top stack element) use std::vector instead. Corresponding operations will be push_back() to place element on stack top, pop_back() to extract element from stack top and back() to access top stack element.

Share:
13,188
Tyler Pfaff
Author by

Tyler Pfaff

Updated on June 04, 2022

Comments

  • Tyler Pfaff
    Tyler Pfaff 4 months
      void PDA::parse(vector<string> words){
        for(int i=0; i<words.size();i++){//for each string in the input file
        string token=words[i];
        for(int j=0; j<token.length(); j++) //for each character in the string
          {
            char input=token[j];
            char matchingBracket=getMatchingBracket(input); //returns the matching bracket, should probably just have ( and [
    
            if(!stack[j]){//since j-1 when the index is 0 will cause an error
              if(stack[j-1]==matchingBracket){
                stack.pop();
              }else{
                stack.push(input);
              }
    
            }
      }
        accepted()?cout<<"The string "<<words[i]<<" is balanced and was accepted"<<endl : cout<<"The string "<<words[i]<<" is not balanced and was not accepted"<<endl;
    }
    }
    

    I'm getting these errors

    PDA.cpp:25: error: no match for âoperator[]â in â((PDA*)this)->PDA::stack[j]â
    PDA.cpp:26: error: no match for âoperator[]â in â((PDA*)this)->PDA::stack[(j - 1)]â
    

    for these lines

    if(!stack[j]){//since j-1 when the index is 0 will cause an error
                  if(stack[j-1]==matchingBracket){
    

    I looked up std::stack and found out that "By default, if no container class is specified for a particular stack class, the standard container class template deque is used." When I looked up deque I found out it supports operator[]. This is how I declared my stack. In the corresponding header file to this source file.

    #ifndef PDA_H
    #define PDA_H
    #include <stack>
    #include <vector>
    #include <deque>
    class PDA{
     private:
      std::stack<char> stack;
     public:
      PDA();
      bool isEmpty();
      void parse(std::vector<std::string>);
      char getMatchingBracket(char);
      bool accepted();
    };
    #endif
    

    As I see it, using operator[] on a std::stack should work just fine. Any ideas?