【问题标题】:How to erase reverse_iterator correctly when erase and push_back happens?当擦除和 push_back 发生时如何正确擦除 reverse_iterator?
【发布时间】:2021-12-28 01:51:18
【问题描述】:

我有一个列表容器,看起来像:

std::list<int> l = {1,2,3,4,5,6,7,8};

我经常擦除元素,所以我选择std::list

但是,我也想在O(1)中找到元素,所以我记录了reverse_iterator。

例如:

  l.push_back(9);
  auto s = l.rbegin();  // record the iterator of 9, in order to erase it in the future fastly.
  cout << *s << endl;
  l.push_back(10);
  auto s2 = l.rbegin();

但是当我这样擦除时:

l.erase(std::next(s).base());  // s the iterator of 9, in my brain

我想擦除 9,但实际上,它擦除了 10。

我有两个问题:

为什么我应该使用next?实际上我的*s 可以获取元素,这与.end() 不同。

如何在我之前保存的迭代器中进行擦除?

【问题讨论】:

  • so i record the reverse_iterator. 为什么不直接录制iterator

标签: c++ stl


【解决方案1】:

由于list的迭代器是双向迭代器,所以不用reverse_iterator,你可以直接用--l.end()获取最后一个值的迭代器。

std::list<int> l = {1,2,3,4,5,6,7,8};
l.push_back(9);
auto s = --l.end(); // record the iterator of 9
l.push_back(10);
l.erase(s); // erase the iterator of 9

Demo.

【讨论】:

    【解决方案2】:

    l.rbegin().base() == l.end(),这里不是最后一个元素的位置,而是链表的末尾。 push_back 再次不会影响这个现有的迭代器,它仍然指向列表的末尾。

    然后 std::next(l.rbegin()).base() == l.end() - 1,现在指向最后一个元素 10

    所以如果你想记住9的位置,你最好使用普通迭代器而不是反向迭代器,或者,使用一个反向迭代器,它的基点指向9,应该是auto s = std::next(l.rbegin()) ,并将其删除为l.erase(s.base())

    规则是&amp;*r == &amp;*(i-1)

    【讨论】:

      猜你喜欢
      • 2012-01-27
      • 2016-05-03
      • 1970-01-01
      • 2012-12-12
      • 2016-03-31
      • 2012-03-17
      • 1970-01-01
      • 2012-07-19
      • 2016-09-16
      相关资源
      最近更新 更多