1

Why would I use a std::stack or a std::queue rather than a std::vector or a std::deque?

Since the container adapters are merely wrappers around the standard containers, why use them at all?

oz1cz
  • 5,504
  • 6
  • 38
  • 58
  • Because there are algorithms that work using stacks and queues. Why not use them over trying to use a list/vector and refactoring all of your algorithms? Unless I'm seriously missing something here. – Ricky Mutschlechner Jun 03 '16 at 06:28
  • Just to prevent *re-inventing the wheel*. True that we can achieve everything - but why do something from scratch if another option is available? Besides, starting from scratch might make our individually developed code buggy and error-prone. – abhishek_naik Jun 03 '16 at 06:32
  • @BatCoder: Who's suggesting starting anything from scratch? He's asking about simply using a normal sequence container like `std::vector` or `std::deque` as a stack or a queue, since they are, of course, perfectly capable of serving those functions. – Benjamin Lindley Jun 03 '16 at 06:40
  • @BenjaminLindley, his statement *Since the container adapters are merely wrappers around the standard containers* strongly makes me feel that he intends to re-implement everything. He won't be able to use the existing functionalities (like `stack.top()`), and have to implement them in his code. – abhishek_naik Jun 03 '16 at 06:45
  • @BatCoder: But there's nothing to implement. You just have to (for a stack) replace calls to `top()` with `back()`, `push(v)` with `push_back(v)`, and `pop()` with `pop_back()`. – Benjamin Lindley Jun 03 '16 at 06:51

3 Answers3

5

To limit the user interface You don't want your stack to be able to remove elements somewhere else instead of top. Why to use vector in place of stack if you have exactly same performance also stack improves readability and reliability.

std::stack is more expressive than std::vector when the container you want to implement is truly a LIFO.

Deepanshu
  • 488
  • 6
  • 18
3
  1. For convenience. They provide a semantic API tailored to the needs.

  2. Readability. stack.top() looks better than stack[0], or stack[stack.size()]*, or stack.back(). Reader of such code does not need to interpret meaning of such a construct. It is given.

*Note: As @moooeeeep suggest it should be size()-1 if anything, but I am leaving original as a nice example why one should use supplied solutions instead of writing even most simple things by hand.

Community
  • 1
  • 1
luk32
  • 15,812
  • 38
  • 62
  • Also the name itself also gives a good idea how they should be used and what they are doing under the hood. – Namoshek Jun 03 '16 at 06:30
  • 1
    or `stack[stack.size()-1]` – moooeeeep Jun 03 '16 at 06:31
  • .@moooeeeep Oh, my bad! *blushy edit*. Btw that is another great reason why. – luk32 Jun 03 '16 at 06:32
  • 1
    And don't forget stack.pop() after a stack.top(). Otherwise the top-element may get re-used which might not be desirable. – kometen Jun 03 '16 at 06:35
  • Maybe it should be neither, as the top element of the stack won't usually be the first or last element of the underlying data structure, but some in-between element. So maybe it rather should be `stack[top_index]` instead. – moooeeeep Jun 03 '16 at 06:43
1

std::stack is an adapter for containers (could be of a vector, a list of whatsnut container). The main purpose is to transform the interface of the underlying container into that one of a stack. Such giving you push(), top() and pop() instead of push_back(), back() and pop_back().

Queue and deque follow the same scheme. A queue is a deque with less operations possible.

moooeeeep
  • 31,622
  • 22
  • 98
  • 187