I notice the thread of similar question: Limit size of Queue<T> in .NET?
That's exactly what I want to do, but I am not using .net but GNU C++. I have no reference to the base class in GNU C++, so java like super.***()
or .net like base.***()
will not work. I have been trying to inherit from queue class but it turns out in vain.
What I want to do:
specify the size of the queue, and automatically dequeue when the queue is full. To be specific: if the maximum size of my queue is 2, when I push the 3rd item, the 1st item will be automatically popped out before pushing the new item.
How to implement such a queue?
Thanks.
Make a new class that encapsulates the queue and enforce a size limit in the new class.
I know you said "automatic", but, to keep things simple: Encapsulate just the Enqueue()
ing in a local function (no, not clean OO, but it works):
Queue<T> myQueue = new Queue<T>();
void addToMyQueue(T param)
{
myQueue.Enqueue(param); //or push(param)
if (myQueue.Count > LIMIT)
myQueue.Dequeue(); //or pop()
}
void main()
{
addToMyQueue(param);
}
It sounds like boost::circuclar_buffer does what you're looking for:
Writing to a Full Buffer
There are several options how to cope
with the case if a data source
produces more data than can fit in the
fixed-sized buffer:
- Inform the data source to wait until
there is room in the buffer (e.g. by
throwing an overflow exception).
- If the oldest data is the most
important, ignore new data from the
source until there is room in the
buffer again.
- If the latest data is the most important, write over the
oldest data.
- Let the producer to be
responsible for checking the size of
the buffer prior writing into it.
It is apparent that the
circular_buffer
implements the third
option. But it may be less apparent it
does not implement any other option -
especially the first two. One can get
an impression that the
circular_buffer
should implement
first three options and offer a
mechanism of choosing among them. This
impression is wrong. The
circular_buffer
was designed and
optimized to be circular (which means
overwriting the oldest data when
full). If such a controlling mechanism
had been enabled, it would just
complicate the matters and the usage
of the circular_buffer
would be
probably less straightforward.
Assuming that by Queue<T>
you mean std::queue<T>
: A queue is just an adapter for some underlying container that's passed at compile-time. You could use a container that already does what you want. The best fit seems to be a circular buffer, if you can find one that supports the operations necessary for std::queue
(I think that's push_back()
, pop_front()
, and size()
, but I haven't checked).