擦除双端队列 C++ 中的多个元素

Erase multiple elements in deque C++

我试图在下面的 'while' 循环中删除双端队列中的多个元素,但我的程序没有给出正确的结果。

问题背景:

packet_deque 包含 9 个 Packet 对象 - 其中一些已发送,其他未发送。

#include <deque> 
#include <iostream> 

class Packet
{
public:
    void set_sent() { sent = true; };
    bool get_sent() { return sent; };
private:
    /* members of Test class */
    bool sent = false;
};

int main()
{ 
    size_t MAX = 9;
    std::deque<Packet> packet_deque(MAX);
    unsigned int i = 0;

    std::deque<Packet>::iterator itr = packet_deque.begin();
    printf("Before erasing sent packets - packet_dequeue size: %d \n", packet_deque.size());
    // initialise the packet queue - creating some sent packets
    for (; itr != packet_deque.end(); ++itr) 
    {
        // set some sent packets
        if (i % 3 == 0) 
        {
            itr->set_sent();
        }
        printf("packet_deque[%d]: %s\n", i, itr->get_sent() ? "sent" : "not_sent");
        ++i;
    }
    printf("\n");

    // erase sent packets in packet_dequeue
    itr = packet_deque.begin();
    while (itr != packet_deque.end())
    {
        if (itr->get_sent())
        {
            // erase the element and do NOT move the pointer
            packet_deque.erase(itr);
        }
        else
        {
            // move to next element
            ++itr;
        }
    }

    printf("After erasing sent packets - packet_dequeue size: %d \n", packet_deque.size());
    for (itr = packet_deque.begin(), i = 0; itr != packet_deque.end(); ++itr) 
    {
        printf("packet_deque[%d]: %s\n", i, itr->get_sent() ? "sent" : "not_sent");
        ++i;
    }
} 

终端输出为:

Before erasing sent packets - packet_dequeue size: 9 
packet_deque[0]: sent
packet_deque[1]: not_sent
packet_deque[2]: not_sent
packet_deque[3]: sent
packet_deque[4]: not_sent
packet_deque[5]: not_sent
packet_deque[6]: sent
packet_deque[7]: not_sent
packet_deque[8]: not_sent

After erasing sent packets - packet_dequeue size: 5 
packet_deque[0]: not_sent
packet_deque[1]: not_sent
packet_deque[2]: not_sent
packet_deque[3]: not_sent
packet_deque[4]: not_sent

问题:

由于 while 循环只删除了 sent 个数据包,我预计有 6 个未发送的数据包,但只有 5 个。 我不知道出了什么问题...... 为什么最终结果只包含5个未发送的数据包而不是6个未发送的数据包?

使用

itr = packet_deque.erase(itr);

否则当前迭代器无效

一般来说,所有迭代器在从双端队列中删除后都会失效。您的代码在 while 条件中使用了无效的迭代器。

但是erasereturns一个新的有效迭代器指向被擦除的元素之后的元素,所以正确的代码是

itr = packet_deque.erase(itr);

引用 doc

All iterators and references are invalidated, unless the erased elements are at the end or the beginning of the container, in which case only the iterators and references to the erased elements are invalidated.

所以你的循环


    while (itr != packet_deque.end())
    {
        if (itr->get_sent())
        {
            // erase the element and do NOT move the pointer
            packet_deque.erase(itr);
        }
        else
        {
            // move to next element
            ++itr;
        }
    }

实际上是错误的。

编辑:您应该使用 itr = packet_deque.erase(itr); 来获得有效的迭代器。