【问题标题】:Get the current object being iterated in a list C++获取列表中正在迭代的当前对象 C++
【发布时间】:2015-08-03 09:12:24
【问题描述】:

所以我有一个列表类AnimalCollection,它继承自list<Animal>

现在我正在实现一个名为 removeById(int id) 的方法,该方法从参数中删除与指定的 id 匹配的集合中的某些项目。

我目前的实现如下:

void AnimalCollection::removeById(int id)
{
    for (auto it = this->begin(); it != this->end(); it++)
    {
        if (it->id == id)
            this->remove((Animal)it);
    }
}

现在,在我的代码的第 6 行,很明显将迭代器转换为当前正在迭代的类型是不明智的。

重点是,我想得到当前被迭代器it迭代的item。

谁知道怎么做?

【问题讨论】:

  • 你不能取消引用it吗?喜欢this->remove(*it);
  • 您在寻找*it吗?
  • 天啊,就是这样,哈哈。我的无知。感谢取消引用部分。拯救了我的一天。
  • 忠告:不要发布带有行号的代码。如果有人复制您的代码,首先必须删除数字,然后才能编译和执行。我会相应地编辑您的问题。
  • 是的,我实际上希望在此处的代码剪切中可以使用行号,这样可以轻松地在代码中指定一个/一些部分,而不是再次复制和粘贴。但是有人编译它会令人沮丧,因为我没有提供 AnimalCollectionAnimal 对象的源代码:D 无论如何,非常感谢伙计。

标签: c++ iterator


【解决方案1】:

std::list#begin() 返回的迭代器是bidirectional iterator。因此,它也是一个 input iterator 并支持解引用运算符 (*it) 来访问被迭代的底层对象:

this->remove(*it);

但请注意,对 remove 的调用将再次遍历列表以查找并删除所有等于 *it 的元素。

或者,您可以使用std::list#erase() 直接从列表中删除迭代器(并且仅删除它引用的元素)并避免可能的无用迭代:

for (auto it = this->begin(); it != this->end(); ) {
    if (it->id == id) {
        it = this->erase(it);
    } else {
        ++it;
    }
}

注意,如果你调用erase(it),你的迭代器it将失效,因此为了继续迭代列表,我们使用erase返回的迭代器指向后面的元素最后移除的元素,可能是end()

【讨论】:

  • 高兴地指出 2 个概念作为我的问题的解决方案。谢谢队友(鞠躬)
  • 警告:如果您使用it = erase(it);,则不应在迭代结束时增加it。否则,擦除最后一个元素将使it 超过end()
  • 警告返回:如果您 erase() 第一个元素,您的修复将在 begin() 之前推送 it ;)
  • 我选择了这个作为最佳答案,因为他完美而完整地阐述了,不仅是解决方案,而且还针对另一个问题提出了可能的对策。其他所有人,感谢您的努力和时间。
  • Caution 很满意,并为您的时间留下了一个赞成票。享受你的咖啡:)
【解决方案2】:

如果您只需要删除it 引用的元素,那么erase(it) 就是您所需要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-01
    • 2019-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多