std :: remove_if是否总是按顺序调用每个元素的谓词(根据迭代器的顺序),还是可以不按顺序调用?
以下是我想做的玩具示例:
void processVector(std::vector<int> values)
{
values.erase(std::remove_if(values.begin(), values.end(), [](int v)
{
if (v % 2 == 0)
{
std::cout << v << "\n";
return true;
}
return false;
}));
}
我需要处理和删除满足特定条件的向量的所有元素,而erase + remove_if似乎是完美的。但是,我将要做的处理有副作用,我需要确保按顺序处理(在玩具示例中,假设我想按照它们在原始矢量中出现的顺序打印值)。
假设我的谓词将按顺序调用每个项目是否安全?
我认为C ++ 17的执行策略会消除歧义,但是由于C ++ 17尚未出现,显然对我没有帮助。
编辑:另外,这是个好主意吗?或者有更好的方法来实现这一目标吗?
答案 0 :(得分:7)
标准不保证调用谓词的顺序。
你应该使用的是stable_partition
。您可以根据谓词对序列进行分区。然后,您可以遍历分区序列以执行您想要执行的任何“副作用”,因为stable_partition
可确保两组数据的相对顺序。然后,您可以删除vector
。
stable_partition
,因为erase_if
未定义“已擦除”元素的内容。
在代码中:
void processVector(std::vector<int> values)
{
auto it = std::stable_partition(begin(values), end(values), [](int v) {return v % 2 != 0;});
std::for_each(it, end(values), [](int v) {std::cout << v << "\n";});
values.erase(it, end(values));
}
答案 1 :(得分:-1)
他们应按顺序处理,但不是保证。
std::remove_if()
将“已删除”项目移动到容器的末尾,在调用erase()
之前,它们实际上并未从容器中删除。这两个操作都可能使std::vector
中的现有迭代器无效。