【问题标题】:C++ Erasing from list of pairsC++ 从对列表中擦除
【发布时间】:2016-08-17 19:34:33
【问题描述】:

非常简单:我有以下代码,但 erase 方法不起作用。我没有看到任何问题,因为如果我去 http://www.cplusplus.com/reference/list/list/erase/ ,语法是:iterator erase (iterator position);

list<pair<string,int>> l0 { { "name1", 20 }, { "name2", 30 }, { "name3", 40 } };
for( auto &it : l0 )
    l0 . erase( it );

可能存在pair&lt;string,int&gt;list 而不是基本数据类型的list 的问题吗?

编辑:问题是代码不可编译。

【问题讨论】:

  • 提示:iterase() 而改变。
  • 除了删除迭代器位置会使该迭代器(或所有迭代器)无效之外,代码不应编译。
  • @DieterLücking 没错,它不会编译。顺便说一句,第一条评论对我没有帮助。请再给我一个提示好吗?
  • @πάνταῥεῖ 你确定这是另一个问题的完全重复吗?我认为 OP 编译他的代码有问题,而不是(还)迭代器无效。
  • @Christophe Exactly.

标签: c++ list erase std-pair


【解决方案1】:

range-for 通过授予您访问 容器中的元素,而不是元素的迭代器。

所以在for( auto &amp;it : l0 ) 中,it 不是一对迭代器,而是 对一对的引用。这就是您的代码无法编译的原因

这就是说,正如πάνταῥεῖ 在他最初关闭它时指出的那样,它是 Keeping a valid vector::iterator after erase(),即使你的代码会 编译它不起作用,因为擦除后迭代器无效:

引用被函数删除的元素的迭代器、指针和引用无效。 所有其他迭代器、指针和引用保持其有效性。

解决方法

你不能使用range-for,而是传统的for,并使用erase()的返回值进行迭代:

for (auto it=l0.begin(); it!=l0.end(); ) 
    it = l0.erase(it);  // to avoid incrementing an invalidated iterator

Live demo

【讨论】:

  • 这个答案是错误的。只有第二个元素会被删除(也可能会超过结尾)。
  • @DieterLücking 你能详细说明一下吗?因为现场演示显示了一些似乎完美运行的东西(erase() 的返回值是“一个迭代器,指向函数调用擦除的最后一个元素之后的元素。如果操作擦除,这是容器结束序列中的最后一个元素。".
【解决方案2】:

Christophe 给出的上述答案是完美的,这对我也有帮助。我想出了这样的东西(我有一些其他的要求)。我希望这可以肯定地帮助某人。 您可以使用remove_if 命令来实现类似的功能。

//Suppose user wants to remove the entry with fits value as "name1"

l0.remove_if([key](auto it) { 
    return it.first == "name1"; 
});

【讨论】:

    猜你喜欢
    • 2014-12-21
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    • 1970-01-01
    • 2012-06-23
    • 1970-01-01
    相关资源
    最近更新 更多