【问题标题】:Removing struct from list based on id根据 id 从列表中删除结构
【发布时间】:2017-07-10 08:27:50
【问题描述】:

我已经创建了一个函数来做到这一点:

void Server::removeClient(unsigned short value) {
    std::list<Client>::iterator itri = clients.begin();
    while (itri != clients.end()) {
        if (itri->id == value) {
            itri = clients.erase(itri);
        } else {
            ++itri;
        }
    }
}

但得到错误:

列表迭代器不可递增

我一直在寻找类似的问题,例如 this one,它说我不应该在我调用擦除之后增加我的迭代器,告诉询问者他们应该将他们的迭代器增量放在我拥有的 else 语句中。

而且我知道这种问题被问了很多,但我真的很困惑。

这里是完整的文档:

Server.h

Server.cpp

注意我的 C++ 文件,我复制粘贴了 mpiatek 的问题链接答案,以确保我的代码是正确的。注释掉的代码和当前代码都不起作用。

我还尝试了 user4581301 建议的 remove_if:

clients.erase(
    std::remove_if(clients.begin(), clients.end(), [&](Client const & c) {
    return c.id == value;
}),
    clients.end());

我从this question. 得到代码它不起作用并返回相同的错误。

【问题讨论】:

  • 拒绝重复。 OP 正在尝试正确执行此操作,并且 I'm unable to reproduceminimal reproducible example,好吗?还可以考虑使用 std::remove_if 作为擦除/删除习语的一部分。
  • 我已将完整文件添加到我的问题中。难道是因为我的列表不是结构指针列表?
  • @hvd 我同意,不好的电话。删除了该评论。
  • 尝试使用std::remove_if。没用,添加到问题中。
  • 您提供的不是最低限度或完整的。你在某处有一个错误,它不在删除中。您可能在某处丢弃了list。当列表在其他地方迭代时,您可能正在从另一个线程调用 remove。开放的可能性太多。

标签: c++ list struct


【解决方案1】:

我相信问题不在于您显示的代码,而在于调用函数。

您在此代码中调用您的 removeClient:

   for (Client &c : clients) {
        c.timeSinceLastPacket+= dt;
        if (c.timeSinceLastPacket.asSeconds() > 10) {
            std::cout << c.id << " has timed out!" << std::endl;
            removeClient(c.id);
        }
    }

一旦removeClient 完成其工作,您的 for 循环正在使用的(隐藏的)迭代器就会失效,并且 for 循环无法继续。

您最好只在外循环中使用迭代器并通过迭代器删除,而不是再次通过 ID 查找。

按照 cmets 的建议,最好使用 std:remove_if 之类的东西

【讨论】:

  • 谢谢!我会在调用我的函数后调用break;
猜你喜欢
  • 2017-09-03
  • 1970-01-01
  • 2021-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多