【问题标题】:Efficiently remove last element from std::list有效地从 std::list 中删除最后一个元素
【发布时间】:2016-08-16 16:30:32
【问题描述】:

这似乎是一个简单的问题,当然是可行的,但我想高效地完成它。

目标
如果满足条件,则从 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 迭代器,但编译器也不喜欢这样。

使用反向迭代器从双向列表中删除列表元素似乎是合理的事情。我这里有什么明显的遗漏吗?

【问题讨论】:

  • 您可以在反向迭代器上调用base(),但您需要自己处理正确的偏移量。
  • @KerrekSB 你能详细说明一下吗?我对迭代器的了解不够,无法知道如何使用您的建议。
  • 我可能在这里遗漏了一个潜台词,but why not pop_back?
  • 嗯,我可能错过了显而易见的事情。我会试试的。
  • FWIW,“ForwardIterator”是有含义的,它不是“不是反向迭代器的迭代器”

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


【解决方案1】:

我想您可以通过以下方式简化您的代码 sn-p:

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

【讨论】:

  • mylist.back()-&gt;Type() == unwanted 更简单。
【解决方案2】:

修复代码中的特定错误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 是您的最佳选择。

【讨论】:

    猜你喜欢
    • 2014-05-20
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 2015-04-20
    • 2010-10-15
    • 2012-01-11
    • 1970-01-01
    • 2018-06-14
    相关资源
    最近更新 更多