【问题标题】:Iterate over container in either direction AND erase elements在任一方向上迭代容器并擦除元素
【发布时间】:2019-01-20 09:11:33
【问题描述】:

我有两个 std::maps:

std::map<int,int> map1;
std::map<int,int> map2;

我需要一个向后迭代,另一个向前迭代(因为这是数据访问的模式)。在迭代时,我希望能够擦除元素继续迭代。

我想用同样的方法。

我已经看到使用模板展示如何进行双向迭代的示例,但没有演示擦除元素(这很重要,因为 erase() 仅适用于前向迭代器):

Iterating over a container bidirectionally

我已经看到了 reverse_iterator 示例,它们可以擦除,但它们不是双向的:

How to call erase with a reverse iterator using a for loop

但我想双向迭代并擦除?

【问题讨论】:

  • 如果只给定一对迭代器,你打算如何从容器中擦除元素?
  • @JonathanWakely 通过传入容器更新的问题来反映。
  • 为什么erase 不能使用反向迭代器?
  • 为什么要擦除print 方法中的元素?也许不是最好的例子;)另外:你想删除哪些元素?
  • @user997112 向前迭代的速度不取决于您弄错的排序标准

标签: c++ c++11 stl iterator


【解决方案1】:

您可以为std::mapstd::setstd::list 编写函数:

template<typename Cont, typename Pred>
void bidir_remove_if( Cont &c, Pred p, bool forward )
{
    auto b = c.begin();
    auto e = c.end();
    while( b != e ) {
       auto it = forward ? b++ : --e;
       if( p(*it) ) {
           auto end = b == e;
           ( forward ? it : e ) = c.erase( it );
           if( end ) break;
       }
    }
}

live example

注意 - 由于迭代器无效,您不能将此函数用于 std::vector(并且您最好不要使用擦除删除习语)。

【讨论】:

  • 非常好,我会试试这个。 std::map 完全安全吗?
  • 除非你在谓词中做了一些花哨的事情,否则应该是这样。但它与std::set 没有什么不同(当然,谓词必须接受std::pair&lt;key,value&gt;
  • e ) = c.erase( it ); 是否真的为向后的情况给出了正确的行为?在我看来,你应该丢弃从erase()返回的“安全”迭代器。
  • @GemTaylor 在反向情况下 it 等于 e 所以e 需要在擦除后重新分配,因此在这种情况下它等于 e = c.erase( e );
  • 是的,但是Return value1-2) Iterator ***following*** the last removed element.
猜你喜欢
  • 2018-09-04
  • 2014-06-11
  • 1970-01-01
  • 2021-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多