Trying to access an index of an std::stack
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 ];
}
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.

Tyler Pfaff
Updated on June 04, 2022Comments
-
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?