我正在尝试这样做:

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


当前回答

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

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

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的返回值

其他回答

如果m_CursorStack是一个向量,你可以通过取index来擦除:

m_CursorStack.erase(m_CursorStack.begin() + m_CursorStack.size() + int(m_CursorStack.rbegin() - i) - 1);

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

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

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(而不是迭代器)。

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

反向迭代器很难使用。使用通用迭代器。'r'从最后一个元素开始。当发现需要抹去的东西时。删除它并返回下一个迭代器。例如当删除第3个元素时,它将指向当前的第4个元素。新的第三个。所以它应该减少1,向左移动

void remchar(string& s,char c)
{      
    auto r = s.end() - 1;
    while (r >= s.begin() && *r == c)
    {
        r = s.erase(r);
        r -= 1;
    }
}

如果你不需要在运行过程中删除所有内容,那么要解决这个问题,你可以使用erase-remove习语:

m_CursorStack.erase(std::remove(m_CursorStack.begin(), m_CursorStack.end(), pCursor), m_CursorStack.end());

remove将容器中与pCursor匹配的所有项交换到最后,并返回指向第一个匹配项的迭代器。然后,使用范围的擦除将从第一个匹配擦除,直到结束。不匹配元素的顺序保持不变。

如果您正在使用std::vector,这可能会更快,其中在内容中间擦除可能涉及大量复制或移动。

当然,上面解释使用reverse_iterator::base()的答案是有趣的,值得了解,为了解决所述的确切问题,我认为std::remove更合适。