473,404 Members | 2,178 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,404 software developers and data experts.

why deque is default for stack?

t
The stack container adaptor uses deque as its default underlying
sequential container. I don't understand why since we only add
elements and remove elements from one side of a stack. Why isn't the
default vector instead? For that matter, why not list since we don't
access elements in the middle of the stack? I don't know if it's
necessary (and don't see that it is) to do so in the implementation of
stack.

Separate question: vector cannot be used for queue adaptor because it
doesn't have push_front. (Lippman C++ Primer, 4th ed, p350). Why
would queue need push_front when we only add to the back of the queue?

Separate question: priority_queue adaptor requires random access and
so can be built using vector or deque but not list (Lippman). Why
does it require random access?

Oct 2 '07 #1
8 3646
t wrote:
The stack container adaptor uses deque as its default underlying
sequential container. I don't understand why since we only add
elements and remove elements from one side of a stack. Why isn't the
default vector instead? For that matter, why not list since we don't
access elements in the middle of the stack? I don't know if it's
necessary (and don't see that it is) to do so in the implementation of
stack.
There is really no decisive reason. For stack sizes that are very small, it
simply won't matter at all, and for large stack sizes std::deque is
marginally more efficient memory-wise and time-wise. A typical
implementation of std::vector will have a memory overhead of about 25%
percent on average, i.e., size() will be about 75% of capacity(). Also,
push_back() in a vector is amortized constant time but will, on average,
involve more than one copy-construction. For std::deque, it is one
copy-construction per push_back(). Access to front() and back() in
std::deque are not worse than for std::vector; only random access to
elements is slightly less efficient. Of course, all this is implementation
dependent anyway. However, the standard was written with established
implementation techniques in mind.

Separate question: vector cannot be used for queue adaptor because it
doesn't have push_front. (Lippman C++ Primer, 4th ed, p350). Why
would queue need push_front when we only add to the back of the queue?
Well, you need pop_front(), which std::vector also does not have.

Separate question: priority_queue adaptor requires random access and
so can be built using vector or deque but not list (Lippman). Why
does it require random access?
Internally std::priority_queue maintains a heap. Inserting and deleting
elements from a heap requires random access.
Best

Kai-Uwe Bux
Oct 2 '07 #2
On 2 Oct, 08:31, t <tmt...@Yahoo.comwrote:
The stack container adaptor uses deque as its default underlying
sequential container. I don't understand why since we only add
elements and remove elements from one side of a stack. Why isn't the
default vector instead? For that matter, why not list since we don't
access elements in the middle of the stack? I don't know if it's
necessary (and don't see that it is) to do so in the implementation of
stack.
Re: list, you have this backwards I think, you wouldn't want
list precisely because you don't need to access the middle of
the stack (and list is less space-efficient than vector or deque).

Perhaps the reason deque is the default is to allow stack<boolto
behave properly in light of the vector<boolfiasco - e.g the "top"
method would require some special gymnastics.

Oct 2 '07 #3
Kai-Uwe Bux wrote:
t wrote:
>The stack container adaptor uses deque as its default underlying
sequential container. I don't understand why since we only add
elements and remove elements from one side of a stack. Why isn't the
default vector instead? For that matter, why not list since we don't
access elements in the middle of the stack? I don't know if it's
necessary (and don't see that it is) to do so in the implementation of
stack.

There is really no decisive reason. For stack sizes that are very small,
it simply won't matter at all, and for large stack sizes std::deque is
marginally more efficient memory-wise and time-wise. A typical
implementation of std::vector will have a memory overhead of about 25%
percent on average, i.e., size() will be about 75% of capacity().
[snip]

Argh, it's late at night and I can't calculate.

a) The two percentages do not match.

b) They are probably bogus anyway. Assuming that the vector uses a simple
doubling strategy, the overhead will be larger on average due to Benford's
law. The exact math is escaping me right now.
Best

Kai-Uwe Bux
Oct 2 '07 #4
On Oct 2, 3:40 am, tragomaskhalos <dave.du.verg...@logicacmg.com>
wrote:
On 2 Oct, 08:31, t <tmt...@Yahoo.comwrote:The stack container adaptor uses deque as its default underlying
sequential container. I don't understand why since we only add
elements and remove elements from one side of a stack. Why isn't the
default vector instead? For that matter, why not list since we don't
access elements in the middle of the stack? I don't know if it's
necessary (and don't see that it is) to do so in the implementation of
stack.

Re: list, you have this backwards I think, you wouldn't want
list precisely because you don't need to access the middle of
the stack (and list is less space-efficient than vector or deque).
std::list uses a linked list implementation, which means that access
to the middle is inefficient, but modifying the end or beginning of it
is rather quick (although, specifically, adding an item may be slower
depending on how quickly the allocator works).

Oct 2 '07 #5
On Oct 2, 9:31 am, t <tmt...@Yahoo.comwrote:
The stack container adaptor uses deque as its default underlying
sequential container. I don't understand why since we only add
elements and remove elements from one side of a stack. Why isn't the
default vector instead?
I've actually wondered about this question myself. Especially because
if one used a vector, dynamic allocations will eventually stop,
whereas
"I think" with a deque, allocations/deallocations will continue.
Vector
seemed more natural for especially a stack, considering that it
only grows to one side.

Werner

Oct 2 '07 #6
werasm wrote:
On Oct 2, 9:31 am, t <tmt...@Yahoo.comwrote:
>The stack container adaptor uses deque as its default underlying
sequential container. I don't understand why since we only add
elements and remove elements from one side of a stack. Why isn't the
default vector instead?

I've actually wondered about this question myself. Especially because
if one used a vector, dynamic allocations will eventually stop,
whereas
"I think" with a deque, allocations/deallocations will continue.
That happens only when the length crosses a blocklength multiple. When you
use a pooling allocator (and the HP/SGI reference implementation of the STL
did), the blocks are not returned to the OS but the allocator keeps them
around for re-use by the container. In that case, reallocation of a block
previously vacated is very cheap.
Vector seemed more natural for especially a stack, considering that it
only grows to one side.

Best

Kai-Uwe Bux
Oct 2 '07 #7
On Oct 2, 10:25 am, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-10-02 09:31, t wrote:
The stack container adaptor uses deque as its default underlying
sequential container. I don't understand why since we only add
elements and remove elements from one side of a stack. Why isn't the
default vector instead? For that matter, why not list since we don't
access elements in the middle of the stack? I don't know if it's
necessary (and don't see that it is) to do so in the implementation of
stack.
Yes, vector, list, and deque can all be used. Why deque was chosen as
default and not vector I do not know, but perhaps it have better
performance when performing lots of push_back and pop_back operations.
As Kai-Uwe pointed out, it will probably involve less copying on
the average. Although it all depends---if you're constantly
pushing and popping, presumably, the vector will reach its
maximum size fairly quickly, and after that, there will be only
one copy per push, just as with deque. (In general, however, I
think that deque is conceived as being "optimal" for pushing and
popping, even at the end, and vector is conceived as being
"optimal" for random access.)
Separate question: vector cannot be used for queue adaptor
because it doesn't have push_front. (Lippman C++ Primer,
4th ed, p350). Why would queue need push_front when we only
add to the back of the queue?
Actually, from what I can see from the standard, Lippman is
wrong. What vector lack is the pop_front method, and just like
you said, push_back is used to add elements.
Of course, push_front and pop_front go together. If a container
implements one, it will implement the other.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Oct 3 '07 #8
Kai-Uwe Bux wrote:
Kai-Uwe Bux wrote:
[snip]
>A typical
implementation of std::vector will have a memory overhead of about 25%
percent on average, i.e., size() will be about 75% of capacity().
[snip]
a) The two percentages do not match.
b) They are probably bogus anyway. Assuming that the vector uses a simple
doubling strategy, the overhead will be larger on average due to Benford's
law. The exact math is escaping me right now.
I think, I figured it out.

Given a simple minded allocation strategy for std::vector that doubles the
capacity every time it needs to reallocate, we have the following:

a) The expected ratio size() / capacity() is

1
--------- approx = 0.72
2 ln(2)

So, on average about 28% of the allocated memory is unused.

b) Filling the vector by a series of push_back() operations will involve on
average

1
4 - ------- approx = 2.56
ln(2)

copy constructor calls.
(I'm just posting this, because it surprised me. I used to belive that a
capacity doubling vector uses about 2 copy constructions per pushback and
is on average 75% filled.)
Best

Kai-Uwe Bux
Oct 3 '07 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Steven Bethard | last post by:
Anyone know why deques don't support slicing? >>> from collections import deque >>> d = deque(i**2 - i + 1 for i in range(10)) >>> d deque() >>> d Traceback (most recent call last): File...
16
by: newsock | last post by:
What differences between queue, deque and priority_queue? And under what situations choose one of them to use? Thanks for your help!
19
by: chris | last post by:
Hello, I've recently been trying to understand the various structures supplied by c++, and the one I find most confusing is deque. One quick question about this. It seems most implementations...
2
by: Robbie Hatley | last post by:
I'm getting a strange warning at work when I compile any file in our product that contains a deque of a particular struct. I don't understand this warning, so I'm not sure if this is a Microsoft...
5
by: yancheng.cheok | last post by:
after reading http://www.codeproject.com/vcpp/stl/vector_vs_deque.asp, i realize that deque has its own speed advantage over vector in all the aspect (except for memory deallocation). does it...
7
by: DevNull | last post by:
Hello everyone, I decided to pick c++ back up after not really having used it much in 10 years. Just as a point of refference, there was no standard C++ last time I used regularly. Anyways...
1
by: katem | last post by:
Here's my problem: I have a class A that uses new to create objects of class B and push them onto a deque, like this (code stripped down for clarity): void ImageOperations::FormMask() { ...
15
by: Juha Nieminen | last post by:
I'm sure this is not a new idea, but I have never heard about it before. I'm wondering if this could work: Assume that you have a common base class and a bunch of classes derived from it, and...
1
Banfa
by: Banfa | last post by:
So the basic sequenced C++ containers are vector - holds data in a contiguous memory block that has the same memory footprint as a classical array. Expensive to insert or delete at the front or...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.