Code goes first:
//.cpp file
template <typename T>
ostream &operator<<(ostream &os, stack<T> &st)
{
while(! st.empty()) {
os << st.top() << " ";
st.pop();
}
return os;
}
template <typename T>
void stack_sorter(stack<T> &st)
{
cout << st << endl; //no output, st is empty?
//...
}
int main()
{
stack<int> s;
s.push(4);
s.push(3);
s.push(5);
cout << s << endl; //ok
stack_sorter(s);
}
output:
5 3 4 //this was the output in main, not in stack_sorter
//empty line, but s is not empty, why?
Question:
As what I did in main, I pass s to stack_soter(), but I got no output in stack_sorter().
What’s wrong?
As others have pointed out,
pop_backmakes your output operation destructive. There is simply no way to read the contents of a stack without emptying it… that’s the nature of a pure stack.Also, it is very poor practice to overload operators for standard types. Because of the way name lookup works (ADL, that is, the way the language finds the overload function to call), it overload functions are supposed to be in the same namespace as the types they overload for. Since you can’t put the function in
std::, the next best alternative is the global namespace, which then pollutes that.But the problem is solvable! Fortunately,
stackprovides for inheritance. The underlying container is accessible to derived classes and it is namedc.Also, having a dedicated class allows you to provide an extra member to hold the separator string, so it can be something besides a simple space character.