限制 C++ 中 Queue<T> 的大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1273026/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 19:25:14  来源:igfitidea点击:

limit size of Queue<T> in C++

c++queuelimitcontainers

提问by Lily

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.

我注意到类似问题的线程:Limit size of Queue<T> in .NET? 这正是我想要做的,但我使用的不是 .net,而是 GNU C++。我没有提到 GNU C++ 中的基类,所以 java likesuper.***()或 .net likebase.***()将不起作用。我一直试图从队列类继承,但结果是徒劳的。

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.

我想做什么:指定队列的大小,并在队列已满时自动出队。具体来说:如果我的队列的最大大小为2,当我推送第3个项目时,在推送新项目之前会自动弹出第一个项目。

How to implement such a queue?

如何实现这样的队列?

Thanks.

谢谢。

采纳答案by Brian Ensink

Make a new class that encapsulates the queue and enforce a size limit in the new class.

创建一个封装队列的新类并在新类中强制执行大小限制。

回答by Engineer

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):

我知道您说的是“自动”,但是,为了简单起见:仅将Enqueue()ing封装在本地函数中(不,不是干净的 OO,但它有效):

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);
}

回答by Michael Burr

It sounds like boost::circuclar_bufferdoes what you're looking for:

听起来boost::circuclar_buffer 可以满足您的需求:

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:

  1. Inform the data source to wait until there is room in the buffer (e.g. by throwing an overflow exception).
  2. If the oldest data is the most important, ignore new data from the source until there is room in the buffer again.
  3. If the latest data is the most important, write over the oldest data.
  4. Let the producer to be responsible for checking the size of the buffer prior writing into it.

It is apparent that the circular_bufferimplements 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_buffershould implement first three options and offer a mechanism of choosing among them. This impression is wrong. The circular_bufferwas 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_bufferwould be probably less straightforward.

写入满缓冲区

如果数据源产生的数据多于固定大小的缓冲区所能容纳的数据量,则有几种方法可以处理这种情况:

  1. 通知数据源等待,直到缓冲区中有空间(例如,通过抛出溢出异常)。
  2. 如果最旧的数据是最重要的,则忽略来自源的新数据,直到缓冲区中再次有空间。
  3. 如果最新的数据最重要,则覆盖最旧的数据。
  4. 让生产者负责在写入缓冲区之前检查缓冲区的大小。

很明显, circular_buffer实现了第三个选项。但它没有实现任何其他选项可能不太明显 - 特别是前两个。人们可能会觉得 circular_buffer应该实施前三个选项并提供一种在其中进行选择的机制。这种印象是错误的。的 circular_buffer设计和优化为圆形(这意味着覆盖最旧的数据时满)。如果启用了这样的控制机制,它只会使事情复杂化,并且 的使用circular_buffer可能会不那么简单。

回答by sbi

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).

假设Queue<T>您的意思是std::queue<T>:队列只是在编译时传递的某些底层容器的适配器。您可以使用已经完成您想要的操作的容器。最合适的似乎是一个环形缓冲区,如果你能找到一个支持必要的行动std::queue(我认为的push_back()pop_front()以及size(),但我没有检查)。