所以我在我的类中有一个方法,这个类应该做的是,检查我.h文件中的向量是否具有值double low
& double high
然后删除它们,最后返回删除了多少“空格”
所以我尝试了一些东西,我总是得到运行时错误,它似乎是在for循环中,但我无法弄清楚原因。
这是我试过的,
首先,我尝试按照我认为可行的方式进行操作:
int datastorage::eraseDataPointsBetween(double low,double high)
{
int antal = 0;
for (vector<double>::iterator i = data_.begin(); i !=data_.end();i++)
{
if (*i >=low && *i <=high)
{
data_.erase(i);
antal++;
}
}
return antal;
}
但后来我尝试做一些调试,我可以看到它实际上没有让它像那样,因为什么东西被删除它仍然会增加(所以如果我们删除“空间2”它实际上会检查下一次空间4(因为点3在擦除后变为点2)))
所以我试着把它改成这个
int datastorage::eraseDataPointsBetween(double low,double high)
{
int antal = 0;
for (vector<double>::iterator i = data_.begin(); i !=data_.end();)
{
if (*i >=low && *i <=high)
{
data_.erase(i);
antal++;
}
else
i++;
}
return antal;
}
每当我不删除空格时它只增加i
(所以如果我删除“空格2”,它将检查新的“空格2”下一次运行)
这也给我一个语法错误expression: vector iterators incompatible
希望你能帮忙,因为我很丢失
答案 0 :(得分:5)
vector::erase
使迭代器无效,因此在调用擦除后无法使用它。
你应该用vector
这样擦除:
int datastorage::eraseDataPointsBetween( double low, double high) {
int antal = 0;
for( vector<double>::iterator i = data_.begin(); i !=data_.end())
{
if( (*i >= low) && (*i <= high))
{
i = data_.erase( i); // new (valid) iterator is returned
++antal;
}
else
{
++i;
}
return antal;
}
答案 1 :(得分:3)
你应该使用remove_if()和erase。这比编写自己的循环更稳定的原因很简单 - 使用无效的迭代器可能会遇到麻烦。
#include <algorithm>
#include <vector>
struct IsBetween
{
double low, high;
IsBetween(double l, double h) : low(l), high(h) {}
bool operator()(double d) const { return d >= low && d <= high; }
};
void datastorage::eraseDataPointsBetween(double low,double high)
{
std::vector<double>::iterator it = std::remove_if(data.begin(), data.end(), IsBetween(low, high));
data.erase(it, data.end());
}
没有循环,请注意remove_if()与函数对象IsBetween的使用。
最重要的是,当您在容器上循环时,应该最小化写入擦除容器中项目的循环的尝试。有remove_if(),remove(),partition()等,它们将您想要关注的数据移动到容器的一端。
尽管你会看到在循环时擦除迭代器的答案,并且看起来很安全,但有多少人会记住返回的规则,或者更简单地说,错误地写入循环? (即使是经验丰富的C ++程序员也可能在第一次切割时错误地编写了循环)。因此,请使用算法为您完成此项工作。
对于remove_if(),&#34; bad&#34;数据移动到最后,您现在可以轻松删除它们。