Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于条件语句删除循环中的向量元素_C++_Vector_Iterator - Fatal编程技术网

C++ 基于条件语句删除循环中的向量元素

C++ 基于条件语句删除循环中的向量元素,c++,vector,iterator,C++,Vector,Iterator,在这个代码段中,Update()返回一个布尔值,如果它返回false,我想从向量中删除元素 但是,这会产生调试断言失败的运行时错误。表达式为“向量迭代器不可递增” 代码: for(auto iter = someVector.begin(); iter != someVector.end(); ++iter){ if(!iter->get()->Update()) iter = someVector.erase(iter); } for(auto iter = partic

在这个代码段中,Update()返回一个布尔值,如果它返回false,我想从向量中删除元素

但是,这会产生调试断言失败的运行时错误。表达式为“向量迭代器不可递增”

代码:

for(auto iter = someVector.begin(); iter != someVector.end(); ++iter){
    if(!iter->get()->Update()) iter = someVector.erase(iter);
}
for(auto iter = particles.begin(); iter != particles.end(); ++iter){
    if(!iter->get()->Update()) iter = --(particles.erase(iter));
}
我也尝试过从迭代器中进行减法,如下所示:

for(auto iter = someVector.begin(); iter != someVector.end(); ++iter){
    if(!iter->get()->Update()) iter = someVector.erase(iter);
}
for(auto iter = particles.begin(); iter != particles.end(); ++iter){
    if(!iter->get()->Update()) iter = --(particles.erase(iter));
}
…但这会导致“向量迭代器不可递减”


如何使代码按预期工作;因此,当Update()函数返回false时,向量元素被删除?

将循环更改为:

for(auto iter = someVector.begin(); iter != someVector.end();){
    if(!iter->get()->Update())
        iter = someVector.erase(iter);
    else
        ++it;
}

断言的原因是,在调用
erase
之后,
iter
可能等于
end()
。“擦除”返回的迭代器已经是“下一个”,您不应该增加它。

将循环更改为:

for(auto iter = someVector.begin(); iter != someVector.end();){
    if(!iter->get()->Update())
        iter = someVector.erase(iter);
    else
        ++it;
}

断言的原因是,在调用
erase
之后,
iter
可能等于
end()
erase
返回的迭代器已经是“下一个”,您不应该增加它。

我建议不要像上面一样使用
erase()
,而是像这样使用它:

someVector.erase(std::remove_if(someVector.begin(), someVector.end(),
                                [](decltype(*someVector.begin()) element){
                                    return !element.get()->update();
                                },
                 someVector.end());

当只需要擦除一个元素时,它的作用与使用一个迭代器版本的
erase()
大致相同。当需要擦除多个元素时,复制/移动的次数会减少。请注意,我使用lambda函数只是因为它更容易表达,但如果lambda函数不可用,也可以使用合适的函数对象来表达。

我建议不要使用首先使用
擦除()
,而是像这样使用它:

someVector.erase(std::remove_if(someVector.begin(), someVector.end(),
                                [](decltype(*someVector.begin()) element){
                                    return !element.get()->update();
                                },
                 someVector.end());

当只需要擦除一个元素时,它的作用与使用一个迭代器版本的
erase()
大致相同。当需要擦除多个元素时,复制/移动的次数会减少。请注意,我使用lambda函数只是因为它更容易表达,但如果lambda函数不可用,也可以使用合适的函数对象来表达。

可能重复+1的可能重复我只写了这个:D,应该是
return!element.get()->update()
谢谢,知道解决问题的多种方法总是很好的。然而,在我的情况下,我很少需要一次擦除超过1个元素。@JoshuaGerrard:使用该算法并不比单独擦除一个元素差,而且在有超过1个元素的罕见情况下效果更好。因此,这显然是要走的路!更不用说,这些算法可能会带来一些额外的性能改进(例如,适当的循环展开、在调试实现中只进行一次边界检查等):使用
std::remove_if()
是一个胜利!再次感谢!我将进一步研究它,因为语法在我看来相当混乱。如果我能理解发生了什么,我会用它。是[](decltype…把我抛到了脑后。也就是说…谷歌是我的朋友;)@JoshuaGerrard:这只是一个C++11 lambda函数,使用
decltype()
来确定参数类型有点笨拙。您还可以使用函数对象,如
struct predict{template bool operator()(T&o){return!o.get()->Update();}然后使用
谓词()
。如果不需要通过
get()。使用
std::bind()
来编写东西也可以,但可能会更加混乱…+1我只写了这个:D,应该是
return!element.get()->update()
谢谢,知道解决问题的多种方法总是很好的。然而,在我的情况下,我很少需要一次擦除超过1个元素。@JoshuaGerrard:使用该算法并不比单独擦除一个元素差,而且在有超过1个元素的罕见情况下效果更好。因此,这显然是要走的路!更不用说,这些算法可能会带来一些额外的性能改进(例如,适当的循环展开、在调试实现中只进行一次边界检查等):使用
std::remove_if()
是一个胜利!再次感谢!我将进一步研究它,因为语法在我看来相当混乱。如果我能理解发生了什么,我会用它。是[](decltype…把我抛到了脑后。也就是说…谷歌是我的朋友;)@JoshuaGerrard:这只是一个C++11 lambda函数,使用
decltype()
来确定参数类型有点笨拙。您还可以使用函数对象,如
struct predict{template bool operator()(T&o){return!o.get()->Update();}然后使用
谓词()
。如果不需要通过
get()。使用
std::bind()
来编写东西也可以,但可能会更加混乱……这非常好,谢谢!我不知道你也可以省略for循环的最后一部分。没问题。也一定要读@Dietmar的答案!至于循环,您可以省略所有三条语句:
for(;;){}
。这就是一些人喜欢写无限循环的方式。我觉得自己受过教育!再次谢谢你。这个很好用,谢谢你!我不知道你也可以省略for循环的最后一部分。没问题。也一定要读@Dietmar的答案!至于循环,您可以省略所有三条语句:
for(;;){}
。这就是一些人喜欢写无限循环的方式。我觉得自己受过教育!再次感谢你。