C++ 向量擦除迭代器
我有以下代码:C++ 向量擦除迭代器,c++,vector,iterator,C++,Vector,Iterator,我有以下代码: int main() { vector<int> res; res.push_back(1); vector<int>::iterator it = res.begin(); for( ; it != res.end(); it++) { it = res.erase(it); //if(it == res.end()) // return 0; } } i
int main()
{
vector<int> res;
res.push_back(1);
vector<int>::iterator it = res.begin();
for( ; it != res.end(); it++)
{
it = res.erase(it);
//if(it == res.end())
// return 0;
}
}
intmain()
{
向量res;
res.push_back(1);
向量::迭代器it=res.begin();
for(;it!=res.end();it++)
{
它=清除(它);
//if(it==res.end())
//返回0;
}
}
一个随机访问迭代器,指向函数调用删除的最后一个元素后面的元素的新位置,如果操作删除了序列中的最后一个元素,则该位置为向量结束
这段代码崩溃了,但是如果我使用if(it==res.end())
部分,然后返回,它就会工作。怎么会?for循环是否缓存res.end()
以使不相等运算符失败?res.erase(it)
始终返回下一个有效迭代器,如果删除最后一个元素,它将指向.end()
在循环结束时,++it
始终被调用,因此您可以递增.end()
,这是不允许的
不过,简单地检查.end()
仍然会留下一个错误,因为每次迭代都会跳过一个元素(it
通过.erase()
的返回“递增”,然后通过循环再次递增)
您可能需要以下内容:
while (it != res.end()) {
it = res.erase(it);
}
删除每个元素
(为了完整性:我假设这是一个简化的示例,如果您只想让每个元素都消失,而不必对其执行操作(例如删除),则只需调用res.clear()
)
当您仅有条件地擦除元素时,您可能需要以下内容
for ( ; it != res.end(); ) {
if (condition) {
it = res.erase(it);
} else {
++it;
}
}
不要擦除然后递增迭代器。无需增加,如果向量的元素数为奇数(或偶数,我不知道),您将错过向量的末尾。it++指令在块的末尾完成。因此,如果您正在擦除最后一个元素,那么您将尝试递增指向空集合的迭代器。您递增
它
超过for循环的循环表达式中(空)容器的末尾
for( ; it != res.end();)
{
it = res.erase(it);
}
或者更一般地说:
for( ; it != res.end();)
{
if (smth)
it = res.erase(it);
else
++it;
}
以下几点似乎也起作用:
for (vector<int>::iterator it = res.begin(); it != res.end(); it++)
{
res.erase(it--);
}
for(vector::iterator it=res.begin();it!=res.end();it++)
{
清除(它--);
}
不确定这是否有任何缺陷?if(allPlayers.empty()==false){
if(allPlayers.empty() == false) {
for(int i = allPlayers.size() - 1; i >= 0; i--)
{
if(allPlayers.at(i).getpMoney() <= 0)
allPlayers.erase(allPlayers.at(i));
}
}
对于(int i=allPlayers.size()-1;i>=0;i--)
{
if(allPlayers.at(i).getpMoney()作为对crazylammer答案的修改,我经常使用:
your_vector_type::iterator it;
for( it = res.start(); it != res.end();)
{
your_vector_type::iterator curr = it++;
if (something)
res.erase(curr);
}
这样做的好处是,您不必担心忘记递增迭代器,这样当您有复杂的逻辑时,迭代器就不那么容易出现错误,它将位于下一个元素,无论您是否从向量中删除它。因为方法erase in vector返回传递的迭代器的下一个迭代器
我将给出如何在迭代时删除向量中的元素的示例
void test_del_vector(){
std::vector<int> vecInt{0, 1, 2, 3, 4, 5};
//method 1
for(auto it = vecInt.begin();it != vecInt.end();){
if(*it % 2){// remove all the odds
it = vecInt.erase(it); // note it will = next(it) after erase
} else{
++it;
}
}
// output all the remaining elements
for(auto const& it:vecInt)std::cout<<it;
std::cout<<std::endl;
// recreate vecInt, and use method 2
vecInt = {0, 1, 2, 3, 4, 5};
//method 2
for(auto it=std::begin(vecInt);it!=std::end(vecInt);){
if (*it % 2){
it = vecInt.erase(it);
}else{
++it;
}
}
// output all the remaining elements
for(auto const& it:vecInt)std::cout<<it;
std::cout<<std::endl;
// recreate vecInt, and use method 3
vecInt = {0, 1, 2, 3, 4, 5};
//method 3
vecInt.erase(std::remove_if(vecInt.begin(), vecInt.end(),
[](const int a){return a % 2;}),
vecInt.end());
// output all the remaining elements
for(auto const& it:vecInt)std::cout<<it;
std::cout<<std::endl;
}
一种更有效的生成方法:
template<class Container, class F>
void erase_where(Container& c, F&& f)
{
c.erase(std::remove_if(c.begin(), c.end(),std::forward<F>(f)),
c.end());
}
void test_del_vector(){
std::vector<int> vecInt{0, 1, 2, 3, 4, 5};
//method 4
auto is_odd = [](int x){return x % 2;};
erase_where(vecInt, is_odd);
// output all the remaining elements
for(auto const& it:vecInt)std::cout<<it;
std::cout<<std::endl;
}
模板
无效删除位置(容器和c、F和F)
{
c、 擦除(std::remove_if(c.begin()、c.end()、std::forward(f)),
c、 end());
}
无效测试_del_vector(){
向量向量{0,1,2,3,4,5};
//方法4
自动为奇数=[](int x){返回x%2;};
擦除其中的(向量,是奇数);
//输出所有剩余的元素
对于(Autoconst & I:VECTEN)STD::CUT你可以用现代C++做的事情是使用“STD::ReaveVIIF”和lambda表达式;
此代码将删除向量的“3”
vector<int> vec {1,2,3,4,5,6};
vec.erase(std::remove_if(begin(vec),end(vec),[](int elem){return (elem == 3);}), end(vec));
向量向量{1,2,3,4,5,6};
向量擦除(std::remove_if(begin(vec),end(vec),[](int-elem){return(elem==3);},end(vec));
类似的问题:因为这只是对代码的简化,所以我并没有试图删除实际代码中的所有元素OK,所以它首先递增,递增后比较No,hidayat;您的代码试图逐个删除向量中的所有元素。为此,您应该从res.begin()开始
,然后永远不要推进迭代器,而是在删除元素时检索返回的迭代器(所有STL容器也是如此)。增量本身就是错误的部分。在真正的代码中,我并没有试图删除所有元素,但谢谢,我现在明白我做错了什么。嗨,我也这么做了,但我仍然得到了“超出范围”的错误。你能告诉我为什么吗?@DukeLover当它等于.end()时,你必须执行迭代器+
)
在某个地方,没有看到任何我能猜到的代码。如果你想不出来,可能会提出一个问题?为什么不使用while
?@chamini2 awhile
循环在这种情况下是等效的。虽然这段代码可以回答问题,但最好解释它的功能并添加一些引用。我不确定c上面的ode。我看到了3个主要问题。首先,在删除后,您不会将res.erase(it)重新签回it
。在删除内容时,您不能让it++在迭代器语句中,因此您应该有一个条件检查来删除它。如果条件失败,那么您应该迭代到下一个(it++
)。虽然我想知道你为什么有它--
?对不起,你为什么还要减少迭代器?如果是这样的话,也许我会绊倒,我道歉。@VG谢谢,我想你的评论解决了答案中的问题,因此很有教育意义,也许值得一提。恐怕我不理解它--
不管怎样,从那以后,桥下流了太多的水…@SkippyleGrandGourou感谢你的回复,我还没有找到与上述递减状态相匹配的东西。这可能是移除后重复一步的情况吗?可能与it=res.erase(it)相同
?尽管我真的很怀疑。Hmmmm@VG:根据Pieter的回答,“res.erase(it)
总是返回下一个有效的迭代器”。我猜it--
和it++
取消,所以据我所知,这段代码一直在擦除
vector<int> vec {1,2,3,4,5,6};
vec.erase(std::remove_if(begin(vec),end(vec),[](int elem){return (elem == 3);}), end(vec));