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.

中的现有迭代器无效