C++ 如何从stl数据结构中删除反向迭代器?
由于某种原因,以下代码失败。不能简单地使用其base()方法擦除反向迭代器C++ 如何从stl数据结构中删除反向迭代器?,c++,stl,iterator,C++,Stl,Iterator,由于某种原因,以下代码失败。不能简单地使用其base()方法擦除反向迭代器 #包括 #包括 int main() { std::一组信息; 一组插入物(1); 插入件(2); 一组插入物(3); std::set::reverse_iterator rev_iter=setofits.rbegin(); std::set::reverse_iterator nextRevIter=setofits.rbegin(); ++Nextite; while(rev_iter!=setofits.ren
#包括
#包括
int main()
{
std::一组信息;
一组插入物(1);
插入件(2);
一组插入物(3);
std::set::reverse_iterator rev_iter=setofits.rbegin();
std::set::reverse_iterator nextRevIter=setofits.rbegin();
++Nextite;
while(rev_iter!=setofits.rend())
{
//找到3并尝试删除
如果(*版本=3)
{
//这里的断层
擦除集合(rev_iter.base());
}
rev_iter=nextRevIter;
++奈斯特维特;
}
}
如何才能正确地做到上述几点?给定一个与要擦除的内容对应的反向迭代器,如何擦除它
注意,很遗憾,擦除不会使用反向迭代器。它需要真实的东西。使用迭代器本身调用
erase
(无需使用base
)
#包括
#包括
int main()
{
std::一组信息;
一组插入物(1);
插入件(2);
一组插入物(3);
std::set::reverse_iterator rev_iter=setofits.rbegin();
while(rev_iter!=setofits.rend())
{
//找到3并尝试删除
如果(*版本=3)
{
rev_iter=擦除设置(rev_iter);
}
其他的
{
++雷沃·伊特尔;
}
}
}
此外,您不需要单独的“下一个”迭代器(参见上面的更改)。更好的方法是使用
std::remove_if
(或类似的函数)。显然,解决方案是base()返回的值为1。以下标识适用于反向迭代器:
&*(reverse_iterator(i)) == &*(i - 1)
或者换句话说,反向迭代器总是一次通过作为其基础的常规迭代器。不知道为什么
在GCC中
简单地改变
// SEGFAULT HERE
setOfInts.erase( rev_iter.base());
到
我当然很好奇,为什么上面的身份是有意义的
在VisualStudio中
回到工作中,在VisualStudio中尝试这个方法,我发现上面的解决方案不太管用。“nextIter”在擦除时变为无效。相反,您需要从擦除中保存临时项以获得下一个迭代器,而不是像上面那样保留下一个迭代器
set<int>::iterator tempIter = setOfInts.erase(--rev_iter.base());
rev_iter = setOfInts.erase(tempIter);
迭代器tempIter=setofits.erase(--rev_iter.base());
rev_iter=擦除设置(临时设置);
因此,最终的解决方案是
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;
}
}
}
intmain()
{
使用名称空间std;
一组信息;
一组插入物(1);
插入件(2);
一组插入物(3);
set::reverse_iterator rev_iter=setofits.rbegin();
while(rev_iter!=setofits.rend())
{
//找到3并尝试删除
如果(*版本=3)
{
cout当您使用反向迭代器进行迭代并希望使用base()修改其容器时,请始终记住,反向迭代器始终基于原始顺序的下一个迭代器。这有点不直观,但实际上使代码更简单:
#include <set>
int main()
{
std::set<int> setOfInts;
setOfInts.insert(1);
setOfInts.insert(2);
setOfInts.insert(3);
typedef std::set<int>::reverse_iterator RevIter;
RevIter rev_iter = setOfInts.rbegin();
while (rev_iter != setOfInts.rend())
{
// Find 3 and try to erase
if (*rev_iter == 3)
setOfInts.erase(--rev_iter.base());
++rev_iter;
}
}
使用的对象(顺序相反)与
1从中,我们知道它只需要迭代器
2从中,我们知道&*(反向迭代器(i))==&*(i–1)。
因此,您可以擦除(-r_v.base())以擦除由“r_v”(和“current-1”)指向的元素:
嗯,擦除不会使用反向迭代器,这是我生命中最后几个小时的总结:)我认为这是因为你可以将一个指针指向数组的末尾,但不能指向数组的开头。因此,如果.rend()==i,那么i.base()==.begin(),而不是.begin()-1(即UB)。因此它始终是一次性的,但在取消引用时,它返回*-->.base()上述标识是为了确保反向迭代器可以在所有标准位置工作,这些标准位置期望迭代器范围指定半开间隔[第一个,最后一个)。如果不是这样的话,反向迭代器在std algos中将是无用的,因为“end”将被取消引用,而“begin”将被跳过。是的,它也提供了一个关于这个问题的逻辑视图。如果你想一想,就像现在一样,基础完全从.end()到.begin(),而不是从--.end()到--.begin(),这不是范围内的精确反向迭代。std::set::erase返回迭代器的事实是Microsoft扩展。
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;
}
}
}
#include <set>
int main()
{
std::set<int> setOfInts;
setOfInts.insert(1);
setOfInts.insert(2);
setOfInts.insert(3);
typedef std::set<int>::reverse_iterator RevIter;
RevIter rev_iter = setOfInts.rbegin();
while (rev_iter != setOfInts.rend())
{
// Find 3 and try to erase
if (*rev_iter == 3)
setOfInts.erase(--rev_iter.base());
++rev_iter;
}
}
riValue = find(riEnd.base(), riBegin.base(), value);
iValue = find(riBegin, riEnd, value);
r_v+1 r_v r_v-1
current-2 current-1 current