std::queue 和 std::deque 清理

shi*_*etu 3 c++ stl std

假设我们有一种情况需要 FIFO 数据结构。例如,按照事件出现的顺序消费一些事件。

此外,我们需要不时地清除整个队列。

std::queue似乎非常适合这样做,但不幸的是它缺乏清理容器的功能。

所以此时我们有两种选择:

std::queue

  • 我们向 STL 库询问我们需要什么。诚然,STL 库将为我们提供更多:它将为我们提供一个std::deque伪装成std::queue
  • 我们只得到了我们需要的一部分,即前弹出和后推,但没有明确的
  • 我们必须以某种方式“模拟”clear,而不是使用循环和弹出的天真方式

std::deque

  • 我们询问 STL 库我们需要什么
  • 我们得到了我们所要求的东西,但是我们得到了太多:我们还得到了前推和后退

总的来说,我们收到的要么太少要么太多,从来都不是我们真正想要的。

这是让我惊讶的事情,当我试图提供清晰的功能来使用 with 时,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);
    }
};
Run Code Online (Sandbox Code Playgroud)

我已经阅读了规格,但我不能确定是否clear_ver_1会保持_pending某种valid but unspecified状态。请参阅那里的字符串示例

我很惊讶规范中关于这个主题的内容如此模糊。难道我没找对地方吗?

谢谢你们!

更新

看来分配和清算之间存在着不可忽视的区别。在内部,队列和双端队列几乎相同(一个使用另一个)

在此输入图像描述

Deb*_*aug 5

的用法std::move

\n

std::move\xc2\xa0isn\ 不应该这样使用。std::move当您不再使用某个对象时,您应该只使用 将其移动到程序中的其他位置。正如您所说,它随后处于有效但未指定的状态

\n
    \n
  • 有效,因为它完全可以安全销毁;
  • \n
  • 未指定,因为您不应再访问该对象。
  • \n
\n

std::queue\xc2\xa0vsstd::deque

\n

如果您只打算使用 FIFO 功能,我建议使用std::queue. 它确实清楚地表明您只会使用std::deque\xc2\xa0 作为 FIFO 数据结构 \xe2\x80\x94 清晰度是std::queue\xc2\xa0 存在的唯一原因。

\n

清除一个std::queue

\n

您可以将其分配给一个空的std::queue,或者像您所做的那样,将其交换为一个空的。

\n
// ...\n\nstruct consumer\n{\n    std::queue<message> _pending;\n\n    void clearQueue()\n    {\n        _pending = {};\n    }\n};\n
Run Code Online (Sandbox Code Playgroud)\n

根据DevSolar的评论编辑

\n

  • @DevSolar:我更困惑为什么双端队列有明确的。也可以使用 ` = {}` 进行重置。然而,它有明确的clear() (2认同)