从std :: list中有效地删除最后一个元素

时间:2016-04-22 22:08:03

标签: c++ list c++11 stl std

这似乎是一个简单的问题,它肯定是可行的,但我想有效地做到这一点。

目标
如果符合条件,则从std :: list中删除最后一个元素。

问题
我的编译器(MSVC ++ 10)不满意将反向迭代器转换为const迭代器,以便对std :: list.erase()进行方法调用。消息是:

error C2664: 'std::_List_iterator<_Mylist>
 std::list<_Ty>::erase(std::_List_const_iterator<_Mylist>)' : cannot
 convert parameter 1 from 'std::reverse_iterator<_RanIt>' to
 'std::_List_const_iterator<_Mylist>'

我试过的代码

std::list<mytype> mylist;

// lots of code omitted for clarity
bool ends_badly = true;

while(ends_badly && mylist.size() > 0)
{
    auto pos = mylist.crbegin(); // Last element in the list
    if ((*pos)->Type() == unwanted)
    {
        mylist.erase(pos); // Here is where the compiler complains
    }
    else
    {
        ends_badly = false;
    }
}

我可以通过使用前向迭代器并循环遍历列表来解决这个问题,但这太麻烦了。在这个上下文中,编译器可以使用正向迭代器,我尝试将反向迭代器转换为const迭代器,但编译器也不喜欢它。

使用反向迭代器从双向列表中删除列表元素似乎是合理的。有什么明显的东西我在这里不见了吗?

2 个答案:

答案 0 :(得分:8)

我认为您可以通过下一种方式简化代码片段:

while (!mylist.empty() && mylist.back()->Type() == unwanted) {
    mylist.pop_back();
}

答案 1 :(得分:3)

修复代码Can I convert a reverse iterator to a forward iterator?

中的特定错误
mylist.erase((pos+1).base()); 

使用std::reverse_iterator::base

  

base迭代器引用下一个元素(从std::reverse_iterator::iterator_type透视图)到reverse_iterator当前指向的元素。

无论如何,pop_back是您的最佳选择。