简体   繁体   English

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

[英]Efficiently remove last element from std::list

This seems like a simple problem, and it is certainly doable, but I'd like to do it efficiently. 这似乎是一个简单的问题,它肯定是可行的,但我想有效地做到这一点。

The Objective : 目标
Remove the last element from a std::list if it meets a condition. 如果符合条件,则从std :: list中删除最后一个元素。

The Problem : 问题
My compiler (MSVC++ 10) is unhappy about casting a reverse iterator to a const iterator for a method call to std::list.erase(). 我的编译器(MSVC ++ 10)不满意将反向迭代器转换为const迭代器,以便对std :: list.erase()进行方法调用。 The message is: 消息是:

 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>' 

The Code I Tried : 我试过的代码

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;
    }
}

I can get around this by using forward iterators and looping through the list to the end, but that's so cumbersome. 我可以通过使用前向迭代器并循环遍历列表来解决这个问题,但这太麻烦了。 The compiler is OK with a forward iterator in this context, and I tried casting a the reverse iterator to a const iterator but the compiler didn't like that either. 在这个上下文中,编译器可以使用正向迭代器,我尝试将反向迭代器转换为const迭代器,但编译器也不喜欢它。

Erasing a list element from a bidirectional list using a reverse iterator seems like a reasonable thing. 使用反向迭代器从双向列表中删除列表元素似乎是合理的。 Is there something obvious I'm missing here? 有什么明显的东西我在这里不见了吗?

I suppose that you can simplify your code snippet doing it the next way: 我想你可以通过下一个方式简化你的代码片段:

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

To fix the specific error in your code Can I convert a reverse iterator to a forward iterator? 修复代码中的特定错误我可以将反向迭代器转换为转发迭代器吗?

mylist.erase((pos+1).base()); 

Using std::reverse_iterator::base 使用std :: reverse_iterator :: base

The base iterator refers to the element that is next (from the std::reverse_iterator::iterator_type perspective) to the element the reverse_iterator is currently pointing to. base迭代器引用next(从std::reverse_iterator::iterator_type透视图)到reverse_iterator当前指向的元素的reverse_iterator

Anyway, pop_back is the best choice in your case. 无论如何, pop_back是您的最佳选择。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM