由于某种原因,以下代码失败。您不能简单地使用它的 base() 方法删除 reverse_iterator。
#include <set>
#include <iostream>
int main()
{
std::set<int> setOfInts;
setOfInts.insert(1);
setOfInts.insert(2);
setOfInts.insert(3);
std::set<int>::reverse_iterator rev_iter = setOfInts.rbegin();
std::set<int>::reverse_iterator nextRevIter = setOfInts.rbegin();
++nextIter;
while ( rev_iter != setOfInts.rend())
{
// Find 3 and try to erase
if (*rev_iter == 3)
{
// SEGFAULT HERE
setOfInts.erase( rev_iter.base());
}
rev_iter = nextRevIter;
++nextRevIter;
}
}
如何正确执行上述操作?给定一个 reverse_iterator 对应于您要删除的内容,您如何删除它?
注意,不幸的是,erase 不会使用 reverse_iterators。它想要真实的东西。
最佳答案
显然,解决方案是 base() 返回的结果是 1。以下身份适用于 reverse_iterator:
&*(reverse_iterator(i)) == &*(i - 1)
或者换句话说,reverse_iterator 总是通过它作为基础的常规迭代器。不知道为什么。
在 GCC 中
简单的改变
// SEGFAULT HERE
setOfInts.erase( rev_iter.base());
到
// WORKS!
setOfInts.erase( --rev_iter.base());
但我确实很好奇为什么上面的身份是有意义的。
在 Visual Studio 中
回到工作岗位并在 Visual Studio 中尝试此操作,我发现上述解决方案不太奏效。 “nextIter”在删除时变得无效。相反,您需要从删除中保存临时值以获取下一个迭代器,而不是像上面那样保留 nextIter。
set<int>::iterator tempIter = setOfInts.erase(--rev_iter.base());
rev_iter = setOfInts.erase(tempIter);
所以最终的解决方案是
int main()
{
using namespace std;
set<int> setOfInts;
setOfInts.insert(1);
setOfInts.insert(2);
setOfInts.insert(3);
set<int>::reverse_iterator rev_iter = setOfInts.rbegin();
while ( rev_iter != setOfInts.rend())
{
// Find 3 and try to erase
if (*rev_iter == 3)
{
cout << "Erasing : " << *rev_iter;
set<int>::iterator tempIter = setOfInts.erase( --rev_iter.base());
rev_iter = set<int>::reverse_iterator(tempIter);
}
else
{
++rev_iter;
}
}
}
注意,关联容器不会从删除返回迭代器。所以这个解决方案不适用于 map 、多 map 等。
关于c++ - 如何从 STL 数据结构中删除 reverse_iterator?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/404258/