发生擦除和push_back时如何正确擦除reverse_iterator?
How to erase reverse_iterator correctly when erase and push_back happens?
我有一个列表容器,它看起来像:
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()
.
不一样
如何在我之前保存的迭代器中进行擦除?
因为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
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())
。
规则是&*r == &*(i-1)
我有一个列表容器,它看起来像:
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()
.
如何在我之前保存的迭代器中进行擦除?
因为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
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())
。
规则是&*r == &*(i-1)