As read on cplusplus.com, std::queue
is implemented as follows:
queues are implemented as containers adaptors, which are classes that use an encapsulated object of a specific container class as its underlying container, providing a specific set of member functions to access its elements. Elements are pushed into the "back" of the specific container and popped from its "front".
The underlying container may be one of the standard container class template or some other specifically designed container class. This underlying container shall support at least the following operations:
......
The standard container classes deque and list fulfill these requirements. By default, if no container class is specified for a particular queue class instantiation, the standard container deque is used.
I am confused as to why deque (a double-ended-queue on steroids) is used as a default here, instead of list (which is a doubly-linked list).
It seems to me that std::deque
is very much overkill: It is a double-ended queue, but also has constant-time element access and many other features; being basically a full-featured std::vector bar the 'elements are stored contiguously in memory' guarantee.
As a normal std::queue
only has very few possible operations, it seems to me that a doubly-linked list should be much more efficient, as there is a lot less plumbing that needs to happen internally.
Why then is std::queue
implemented using std::deque
as default, instead of std::list
?
It appears that the way deque is usually implemented is a variable size array of fixed size arrays. This makes growing faster than a vector (which requires reallocation and copying), so for something like a stack which is all about adding and removing elements, deque is likely a better choice.
Queues use an encapsulated object of deque or list (sequential container class) as its underlying container, providing a specific set of member functions to access its elements.
Suitable underlying container classes for queue include deque and list , or any other sequence container that supports the operations of front , back , push_back , and pop_front .
A queue is a simple data structure where the insertion and deletion of elements take place from the one end, whereas Deque is a hybrid data structure serving the purpose of both the stack and queue and insertion and deletion of elements can take place from both the ends according to the requirements of the user.
Stop thinking of list
as "This is awkward to use, and lacks a bunch of useful features, so it must be the best choice when I don't need those features".
list
is implemented as a doubly-linked list with a cached count. There are a narrow set of situations where it is optimal; when you need really, really strong reference/pointer/iterator stability. When you erase and insert in the middle of a container orders of magnitude more often than you iterate to the middle of a container.
And that is about it.
The std
datatypes were generally implemented, then their performance and other characteristics analyzed, then the standard was written saying "you gotta guarantee these requirements". A little bit of wiggle room was left.
So when they wrote queue
, someone probably profiled how list
and deque
performed and discovered how much faster deque
was, so used deque
by default.
In practice, someone could ship a deque
with horrible performance (for example, MSVC has a tiny block size), but making it worse than what is required for a std::list
would be tricky. list
basically mandates one-node-per-element, and that makes memory caches cry.
The reason is that deque is orders of magnitude faster than list. List allocates each element separately, while deque allocates large chunks of elements.
The advantage of list is that it is possible to delete elements in the middle, but a queue does not require this feature.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With