我正在尝试这样做:

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


当前回答

请注意m_CursorStack。如果在for循环中使用erase((++i).base())可能是一个问题(见原始问题),因为它改变了i的值。正确的表达式是m_CursorStack.erase((i+1).base())

其他回答

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

m_CursorStack.erase(m_CursorStack.begin() + m_CursorStack.size() + int(m_CursorStack.rbegin() - i) - 1);
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::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;
}

为了补充其他人的答案,因为我在搜索std::string时偶然发现了这个问题,没有太多成功,这里有一个使用std::string, std::string::erase和std::reverse_iterator的响应

我的问题是从一个完整的文件名字符串中删除一个图像文件名。它最初是用std::string::find_last_of解决的,但我研究了std::reverse_iterator的替代方法。

std::string haystack("\\\\UNC\\complete\\file\\path.exe");
auto&& it = std::find_if( std::rbegin(haystack), std::rend(haystack), []( char ch){ return ch == '\\'; } );
auto&& it2 = std::string::iterator( std::begin( haystack ) + std::distance(it, std::rend(haystack)) );
haystack.erase(it2, std::end(haystack));
std::cout << haystack;  ////// prints: '\\UNC\complete\file\'

它使用算法、迭代器和字符串头。

虽然在这里使用reverse_iterator的base()方法并对结果进行递减,但值得注意的是,reverse_iterators的状态与常规迭代器不同。一般来说,您应该更喜欢常规迭代器而不是reverse_iterators(以及const_iterators和const_reverse_iterators),原因正是如此。有关原因,请参阅多布斯医生杂志进行深入讨论。