提问人:shiretu 提问时间:3/31/2022 最后编辑:shiretu 更新时间:4/1/2022 访问量:1114
std::queue 和 std::d eque 清理
std::queue and std::deque cleanup
问:
假设我们有一个情况,我们需要FIFO数据结构。例如,按事件出现的顺序使用某些事件。
此外,我们需要不时清除整个队列。
std::queue
似乎非常适合这样做,但不幸的是,它缺乏清理容器的功能。
因此,在这一点上,我们有 2 种选择:
std::queue
- 我们问 STL 库我们需要什么。诚然,STL 库会给我们更多:它会给我们一个伪装成一个
std::deque
std::queue
- 我们只从我们需要的东西中取回了一部分,即弹出前和推回,但没有明确
- 我们将不得不以某种方式“模仿”清除,而不是循环和弹出的幼稚方式
std::deque
- 我们问 STL 库我们需要什么
- 我们得到了我们要求的东西,但我们得到了太多:我们也得到了前推和后推
总的来说,我们得到的要么太少,要么太多,从来都不是我们真正想要的。
这是让我感到惊讶的事情,当我试图提供明确的功能来使用我的对象的成员 var 时std::queue
struct message
{
};
struct consumer
{
std::queue<message> _pending;
void clear_ver_1()
{
auto will_be_deleted_when_out_of_scope = std::move(_pending);
}
void clear_ver_2()
{
std::queue<message> will_be_deleted_when_out_of_scope;
_pending.swap(will_be_deleted_when_out_of_scope);
}
};
我已经阅读了规格,我不能确定是否会保持状态。请参阅此处的字符串示例。clear_ver_1
_pending
valid but unspecified
我很惊讶这个话题的规格如此模糊。我是不是找对地方了?
谢谢大家!
更新
分配和清算之间似乎存在不可忽视的区别。在内部,queue 和 deque 几乎相同(一个使用另一个)
答:
要清除队列,您也可以简单地编写
_pending = {};
注意:第一种方法可能不起作用,不应依赖,因为移动表单对象处于有效但未指定的状态。
我们得到了我们要求的东西,但我们得到了太多:我们也得到了前推和后推
你得到了你所要求的,a 是一种数据结构,允许在任一端点进行有效的插入和删除。它可能不是适合您的数据结构,但这是您选择它的错。dequeue
我们将不得不以某种方式“模仿”清除,而不是循环和弹出的幼稚方式
根据记录,爆裂在性能方面非常便宜,它只是递减了一个数字。在 while 循环中弹出一个整数转换为将整数递减到 0,除非你有很多数字,否则这是非常快的。事实上,它可能比分配内存快得多,这给我们带来了:
清除这些集合类的 STL 方法是将它们与空集合交换(这是你自己想出的),或者直接将它们重新分配到位(Apple 的答案)。这两种方法(可能,标准在这一点上是模糊的)都会分配内存,这是一个非常昂贵的线性操作。
你有所有的部分来做这件事,尽管我建议分析一下,看看哪种方式更快,如果它真的对你很重要。就我个人而言,我只是将队列弹出一个循环,它会将分配的内存保留在原位,以备下次我需要推送更多时使用,因此它可以节省潜在的多次分配和重新分配(与重置队列相比),具体取决于您拥有的数据量。
评论
dequeue
vector
的用法std::move
std::move
并不意味着以这种方式使用。你应该只使用 ,好吧,当你不再使用它时,将对象移动到程序中的其他位置。正如您所说,它随后处于有效但未指定的状态:std::move
- 有效,因为它完全可以安全地销毁;
- 未指定,因为您不应再访问该对象。
std::queue
与std::deque
如果您只打算使用 FIFO 功能,我建议使用 .它清楚地表明,你只会用作 FIFO 数据结构——清晰度是首先存在的唯一原因。std::queue
std::deque
std::queue
清除std::queue
您可以将其分配给空的,或者像您所做的那样,将其换成空的。std::queue
// ...
struct consumer
{
std::queue<message> _pending;
void clearQueue()
{
_pending = {};
}
};
根据DevSolar的评论进行编辑
评论
clearQueue
_pending = {}
std::queue
std::stack
std::queue
std::deque
std::queue< message, std::map >
clear()
clear()
clear()
评论
clear_ver_2
meaning the object's class invariants hold (so functions without preconditions, such as the assignment operator, can be safely used on the object after it was moved from)
)