overloading stuff for std::stack

G'day all.
Im trying to create a stack function that will print the entire contents of the stack - but the problem is the STL doesnt like it.
it looks something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using namespace std;
template < typename T, typename Seq >
void stack<T, Seq>::printStack(){
    int temp = s.size();
    T * contents = new T [s.size() + 6];
    int counter = -1;
    while(!s.empty()){
        T top = s.top();
        s.pop();
        contents[counter++] = top;
    }
    for(int i = 0; i < counter; i++){
        fprintf(out, "%c ", contents[i]);
        s.push(contents[i]);
    }
    return;
    }

Im aware that the fprintf line only prints a char (right now, that's just for simplicty and i'll probably change it to an iostream later on), but my problem is that it doesnt compile.
The error is that std::stack<T, Seq> doesnt have a member named printStack.(more specifically,
 
error: no `void std::stack<_Tp, _Sequence>::printStack()' member function declared in class `std::stack<_Tp, _Sequence>'
)
I know that i could add this to the STL's implementation on my computer, but im looking at making the code compile on other computers (and not just send around a binary file) and so this is out of the question.
Do you have any suggestions on how to do this? (as in, just make it compile for now)
Thanks,
Ben
Don't make it a member function of stack<>.

(It doesn't need to be anyway).

by "Don't make it a member function of stack<>", do you mean just keep it as a seperate function?
as in, instead of calling stack<T, Seq>::printStack just call printStack?

That's what i've reverted to doing, but out of curiosity is there anyway to do such a thing (declare a function as part of something from the STL so i dont have to call printStack(s) and just call s.printStack)?

cheers for the help
Yes, that is what I mean.

No, there isn't without modifying the header file where stack is declared.
Alternatively you could derive from stack<> but I wouldn't recommend it.
Yeah, deriving from stack<> was what I'd head about (and originally trying to find an answer for, even though i just took the easy way and implemented it as a simple function)

Would it be too much trouble to ask for an explanation as to how to derive from stack<>?
I don't know what template parameters stack has off the top of my head, so you'll need to change my template parameters accordingly:

1
2
3
4
template< typename T, typename Seq >
class my_stack : public stack< T, Seq > {
   // ...
};


Note that base class pointers must not be used to delete your object once you derive from stack.

A better, but more involved, solution may be to write an adapter class that maintains a stack as a member and forwards most calls to that member.
@jsmith

so with that class, i would only have to add the printStack function for it to work? I didnt realise that you could do class my_stack : public stack< T, Seq >
Does that declare a class that has access to public members of stack<>?

@seymore

Honestly, i have no idea what that first line means. I also have no idea no idea how to implement the second solution :)
Care to elaborate?
Does that declare a class that has access to public members of stack<>?

Sure does. All you would have to do is add your printStack member.

Care to elaborate?

No problem. The first line means that if you dynamically allocated memory for an object of a class that is derived from a stack, you must be careful when deleting that object. A stack does not have a virtual destructor, so that if you use a pointer to a stack to pass your derived object around and then call delete on it; only the stack portion of the object would be destroyed resulting in a memory leak. If this were a large project involving users other than yourself, you may not want to take the risk that your class could be used in this way. On the other hand, if you are just writing a program for your own use, deriving from stack will save you a lot of work.


If the above situation would be a concern, then you could consider creating a class that contains a member that is a stack. Any method that you normally call on a stack would have to be made available from your class explicitly.

For example:

1
2
3
4
5
6
7
8
9
template <class T>
class stack_wrapper
{
    stack<T> data;
public:
    size_t size() const { return data.size(); };
    // ...
    void printStack() { /* ... */ }
};


In the above example, the size() method is now available for objects of class stack_wrapper. It's implementation simply passes the request on to the real underlying stack<T> object data.


It could then be used just as you wanted:

1
2
3
stack_wrapper<int> mystack;
// ...
mystack.printStack();



All in all, the best idea is still just to have a template function that takes a stack<T> reference and prints out the contents.
Last edited on
ahh, right, i understand the adapter classes now. That doesnt seem like too much trouble, really.

Im still a little shady on the deriving from stack thing (the pointers etc. (this probably boils down to the fact that i try to avoid pointers as much as i can, i cant stand the segfaults)).
If (in the code i wrote above) i called delete[] contents, would that cause the problem you're referring to?
Or would the problem be when im delete-ing a reference to stack< T, Seq >& some_stack?
Thanks for the help thus far
Unless you are using polymorphism for your stack-derived objects (by referring to them through a base class pointer) there should be nothing to worry about.

Again, though, printStack would be best as a non-member function that takes a stack as a parameter.
Last edited on
ahh right, gotcha.
Thanks for all your help
Topic archived. No new replies allowed.