3

Numerous answers and comments on SO claim that using std::stack is pretty much useless, but don't really give a reason other than "Use a std::vector or std::deque instead."

Why? What's wrong with it?

Evidence of Claims:

Community
  • 1
  • 1
Casey
  • 10,297
  • 11
  • 59
  • 88
  • 3
    I've never seen anyone claim that, but one thing to consider is that it doesn't expose iterators. It's fine if all you need to do is push and pop. – chris Sep 27 '15 at 16:50
  • 7
    Indeed, you can use `push_back()` and co. directly with a container, but stack has a purpose: be explicit about the stack-like behavior. – curiousguy Sep 27 '15 at 16:51
  • 1
    Provide evidence for your claim! – Walter Sep 27 '15 at 17:34
  • `std::stack` only allows you to access the top element of the stack. So if you implement some stack-based algorithm using `std::stack` and that find that you need to access one-under-top element you have to convert your code to use `std::vector`. – cubuspl42 Sep 27 '15 at 17:39
  • @CaptainObvlious See edit. – Casey Sep 27 '15 at 19:48
  • @Casey sorry, but it appears you have misread almost all those answers. The one answer that outright claims `std::stack` is useless is very disagreeable. I edited errikos answer to make the point even more clear. – Walter Sep 28 '15 at 11:37

2 Answers2

10

There is a saying that goes like this:

Don't tempt someone to do something you don't want him/her to do.

A stack is a well-defined data structure. It's behaviour is well implemented by std::stack.

If all you need is a stack and nothing more, then go for std::stack. It will help you stick to the purpose of the data structure, plus make your program clearer to understand and easier to maintain.

But try to evaluate whether you will ever need more functionality than a stack provides.

For example, a good reason to argue in favour of std::deque or std::vector is iterators, as already stated.


In all cases provided as evidence for the fact that using std::stack is pretty much useless, it was such additional functionality (beyond that of a stack) which motivated abandoning std::stack in favour of another container.

Walter
  • 44,150
  • 20
  • 113
  • 196
ergysdo
  • 1,139
  • 11
  • 20
  • "It will help you stick to the purpose of the data structure" honestly, this is extremely flimsy as a reason to use it; if I need to take a peek at the second-top element it's because I need it, not because I have nothing better to do, and doing a pop/push dance just not to break the illusion that I don't know that it's a `deque` under there (jeez, it's even statically written in its type!) is just plain stupid. – Matteo Italia Sep 28 '15 at 22:16
  • (this is especially true because stacks don't live in a void - it's not so frequent to just use a stack as-is, typically either you use the accumulated elements at the end, or you may just want to print them out for debugging purposes; `std::stack` makes all this a PITA for dubious reasons, and makes changing the code to the "real" container another PITA because it uses different names for the methods) – Matteo Italia Sep 28 '15 at 22:33
  • 1
    That's what I am trying to say. If you need to peek the second element, then probably a stack is useless to you. But that does not make `std::stack` useless. – ergysdo Sep 28 '15 at 23:43
  • and if I don't need it for now, what is the advantage of disabling iterators and element access? Mind you: it's not like std::stack forces some kind of postcondition (contrast with std::priority_queue), every state that can be reached manipulating a vector can be reached with an appropriate (inefficient) push/pop dance (general case: pop all the elements in aa new vector, manipulate the vector, push them again in the stack), so it doesn't even give any guarantee of correctness. – Matteo Italia Sep 29 '15 at 06:07
  • IOW: *why do you care that your code or your clients are forced to use your vector like a stack*, given that all the vector states are reachable anyway? (that would be a different thing if std::stack exploited the interface restriction to do something useful - say, performing type erasure and abstract the underlying container type, or providing a lock-free thread-safe stack or whatever) – Matteo Italia Sep 29 '15 at 06:17
0

Let's say std::stack is not useless but it is only a reasonable choice if one of the following is true:

  1. You do not mind using raw loops instead of making idiomatic use of the standard algorithms.
  2. You will never need to deal with more than one stack item at a time in a single function, method, or semantic unit in your code.

Basically std::stack's lack of any kind of iterator interface means that it can't be used with any of the standard algorithms, if this is a problem to you then use a vector you treat as a stack or roll your own stack template.

jwezorek
  • 8,592
  • 1
  • 29
  • 46