如何删除 C++ 列表中迭代器指向的元素?

How do I remove element pointed to by iterator in a C++ list?

如何删除 C++ 列表中迭代器指向的元素?为什么这不起作用?

int main()
{
    list<int> l;
    l.push_back(5);
    l.push_back(6);

    
    for(auto &it: l)
    {
        l.erase(*it);
    }

    return 0;
}
int main()
{
    list<int> l;
    list<int>::iterator it;
    l.push_back(5);
    l.push_back(6);
    l.push_back(7);
    it=l.begin();// points to the first element
    l.erase(it);//pass the iterator to the erase method
    
    for(auto i=l.begin();i!=l.end();i++){
        cout<<*i<<" ";
    }

    return 0;
}

假设您想删除第一个元素。然后简单地将列表的迭代器传递给 erase 方法。

如果你想在循环中做 cpprefenrence 有很好的例子

当使用 erase 方法删除元素时,它 return 是下一个 iterator 删除的元素,如果最后一个元素 end 将 return;

std::list<int> l{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

从上面的列表中,假设您要删除 4 和 5;

下面是方法;

std::list<int>::iterator first = l.begin();

std::advance( first, 4 );
auto it = l.erase( first ); // removes 4 and returns iterator to element 5
l.erase( it ) // removes 5;

正如其他人所建议的那样:

for(auto &it: l){ // range based loop, iterating through elements ex: 4, 5, 6
  //l.erase(*it);
  std::cout << it; // prints 4, 5, 6

}

您需要低于 for loop 才能增加 iterator

for( auto it = l.begin(); it != l.end(); it++) 
{
   // do something hear
}

为什么

for(auto &it: l){
    l.erase(*it);
}

无法工作:

it 不是迭代器。在 range-based for loop 中,冒号前声明的变量 range_declaration 将在容器中接收一个项目,在本例中为 int。由于 it 将收到 intauto 将推断出 int 的类型,从而导致

for(int &it: l){
    l.erase(*it);
}

std::list::erase 需要一个迭代器。我假设 * 只是一些霰弹枪调试的结果,以查看取消引用被认为是迭代器的东西是否有帮助(它不会)。

旁注:您不能在使用基于范围的 for 循环迭代容器时从容器中移除项目。实现 for 循环的后台魔术看起来像

{
    auto cur = container.begin() ;
    auto end = container.end();
    for ( ; cur != end; ++cur) 
    {
        auto val = *cur;
        do_stuff 
    }
}

如果在 do_stuff 中从容器中删除 cur,则 ++cur 无效。由于 cur 不再位于容器中,因此您无法使用它前进到容器中的下一个项目。 std::list 在其 iterator invalidation rules 中非常宽容。当缓存的 end 迭代器失效时,许多容器将失败。

如何修复:

给定的代码似乎试图清空 list 中的所有项目。 std::list::clear 通过单个函数调用为您完成。

如果要按值释放特定元素或 select 个元素,应将 std::list::remove or std::list::remove_ifstd::list::erase

结合使用

例如:

l.erase(l.remove(5), l.end()); // remove all elements containing the number 5

如果要删除第一项,std::list::pop_front. To remove the last item, std::list::pop_back. If you want to remove any other element by position, you must have a valid iterator for that position (If you do not already have one, see std::advance) 然后调用 erase。请注意,如果您必须进行大量迭代才能找到要删除的项目,std::list 可能不是这项工作的正确容器,因为 list 迭代很昂贵并且很快就会消除廉价插入和删除的好处.

如果您使用基于迭代器的循环,您可以使用 erase 的 return 值来更新迭代器:

  std::list<int> l = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

  for (auto it = l.begin();
       it != l.end();
       ++it)
  {
    if (*it % 3 == 0)
    {
      it = l.erase(it);
    }
  }
  for (auto i : l)
  {
    std::cout << i << std::endl;
  }