std::remove_if 是否保证按顺序调用谓词?
Is std::remove_if guaranteed to call predicate in order?
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 尚未发布,这显然对我没有帮助。
编辑:还有,这是个好主意吗?或者有更好的方法来完成这个吗?
标准不保证调用谓词的顺序。
你应该使用的是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));
}
他们应该按顺序处理,但不保证。
std::remove_if()
将 "removed" 项移动到容器的末尾,直到调用 erase()
时它们才真正从容器中移除。这两个操作都可能使 std::vector
.
中的现有迭代器无效
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 尚未发布,这显然对我没有帮助。
编辑:还有,这是个好主意吗?或者有更好的方法来完成这个吗?
标准不保证调用谓词的顺序。
你应该使用的是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));
}
他们应该按顺序处理,但不保证。
std::remove_if()
将 "removed" 项移动到容器的末尾,直到调用 erase()
时它们才真正从容器中移除。这两个操作都可能使 std::vector
.