我正在尝试这样做:

for ( std::list< Cursor::Enum >::reverse_iterator i = m_CursorStack.rbegin(); i != m_CursorStack.rend(); ++i )
{
    if ( *i == pCursor )
    {
        m_CursorStack.erase( i );
        break;
    }
}

但是erase需要一个迭代器,而不是反向迭代器。有没有一种方法可以将反向迭代器转换为常规迭代器,或者另一种方法可以从列表中删除该元素?


当前回答

经过更多的研究和测试,我找到了解决方案。显然,根据标准[24.4.1/1],i.base()和i之间的关系是:

&*(reverse_iterator(i)) == &*(i - 1)

(摘自多布斯博士的文章):

因此,在获取base()时需要应用偏移量。因此解决方案是:

m_CursorStack.erase( --(i.base()) );

EDIT

针对c++ 11进行更新。

Reverse_iterator I不变:

m_CursorStack.erase( std::next(i).base() );

Reverse_iterator I是高级的:

std::advance(i, 1);
m_CursorStack.erase( i.base() );

我发现这比之前的解清楚多了。你需要什么就用什么。

其他回答

有趣的是,这个页面上还没有正确的解决方案。所以,下面是正确的答案:

对于前向迭代器,解决方案是直接的:

std::list< int >::iterator i = myList.begin();
while ( i != myList.end() ) {
  if ( *i == to_delete ) {
    i = myList.erase( i );
  } else {
    ++i;
  } 
}

在反向迭代器的情况下,你需要做同样的事情:

std::list< int >::reverse_iterator i = myList.rbegin();
while ( i != myList.rend() ) {
  if ( *i == to_delete ) {
    i = decltype(i)(myList.erase( std::next(i).base() ));
  } else {
    ++i;
  } 
}

注:

你可以从一个迭代器构造一个reverse_iterator 你可以使用std::list::erase的返回值

只是想澄清一些事情:在上面的一些评论和回答中,erase的便携版本被提到为(++i).base()。然而,除非我遗漏了一些东西,否则正确的语句是(++ri).base(),这意味着你“增加”reverse_iterator(而不是迭代器)。

昨天我遇到了类似的事情,这篇文章很有帮助。谢谢每一个人。

下面这段代码将擦除的结果转换回反向迭代器,以便在反向迭代时擦除容器中的元素。有点奇怪,但它即使在擦除第一个或最后一个元素时也能工作:

std::set<int> set{1,2,3,4,5};

for (auto itr = set.rbegin(); itr != set.rend(); )
{    
    if (*itr == 3)
    {
        auto it = set.erase(--itr.base());
        itr = std::reverse_iterator(it);            
    }
    else
        ++itr;
}
typedef std::map<size_t, some_class*> TMap;
TMap Map;
.......

for( TMap::const_reverse_iterator It = Map.rbegin(), end = Map.rend(); It != end; It++ )
{
    TMap::const_iterator Obsolete = It.base();   // conversion into const_iterator
    It++;
    Map.erase( Obsolete );
    It--;
}

... 或者从列表中删除该元素的另一种方法?

这需要-std=c++11标志(用于auto):

auto it=vt.end();
while (it>vt.begin())
{
    it--;
    if (*it == pCursor) //{ delete *it;
        it = vt.erase(it); //}
}