【问题标题】:How do you erase *AND CONTINUE* using a std::reverse_iterator?如何使用 std::reverse_iterator 擦除 *AND CONTINUE*?
【发布时间】:2012-01-27 03:08:00
【问题描述】:

我一直在使用 stackoverflow,甚至是非常非常好的Dr. Dobbs article,但我找不到这个问题的明确答案。

What are the shortcomings of std::reverse_iterator? 问题答案的一部分说这可能根本不可能。


std::list::reverse_iterator it = list.rbegin();

while(  it != list.rend() )
{
   int value=*it;
   if( some_cond_met_on(value) )
   {     
        ++it;
        list.erase( it.base() );
   }
   else
   {
     ++it;
   }
}

PS:我知道还有其他替代方法,例如 erase_if(),但我正在寻找这个特定问题的答案。

【问题讨论】:

    标签: c++ stl iterator erase


    【解决方案1】:

    应该是

    std::list<int>::reverse_iterator it = list.rbegin();
    
    while(  it != list.rend() )
    {
       int value=*it;
       if( some_cond_met_on(value) )
       {     
            ++it;
            it= reverse_iterator(list.erase(it.base()); // change to this!
       }
       else
       {
         ++it;
       }
    }
    

    【讨论】:

    • 我试试看。你是怎么想出这个的? (只是要求学习如何学习)
    • @Migs,反向迭代器的不变量是:&amp;*(reverse_iterator(i))==&amp;*(i - 1)。从那里向后映射(或者只是考虑删除rbegin()),你就会得到答案中的代码。
    • 感谢@MSN。它工作得很好。我在 Dobbs 的文章中读到了这个不变量,但我想我无法理解它的含义。我会一直盯着看,直到(希望)发生一些事情。
    • @Migs,我也不得不考虑一下。但是,如果您考虑删除[0, 1, 2, 3, 4] 中的rbegin() + 1,则删除正确的前向迭代器(通过.erase())的结果正是您希望在其上构建反向迭代器的位置。
    • 该代码无法在 Visual Studio 中编译。你不是说it = std::list&lt;int&gt;::reverse_iterator(list.erase(it.base()));。还有一个问题,像static_cast&lt;std::list&lt;int&gt;::reverse_iterator&gt;(list.erase(it.base())); 这样的静态演员不是更好吗?谢谢
    【解决方案2】:

    我见过的大多数erase() 实现都会针对这种情况返回序列中的下一个迭代器,例如:

    std::list<int>::reverse_iterator it = list.rbegin();
    while( it != list.rend() )
    {
        int value = *it;
        if( some_cond_met_on(value) )
        {
            it = list.erase( it );
        }
        else
        {
            ++it;
        }
    }
    

    【讨论】:

    • 这是正确的。但是,erase 是结构的成员,而不是迭代器。因此,无论您使用的是迭代器还是 reverse_iterator,erase() 仍然接受并返回一个迭代器。没有 r_erase(),它接受并返回一个 reverse_iterator。
    猜你喜欢
    • 2021-12-28
    • 2016-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    相关资源
    最近更新 更多