5

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 还没有出现,这显然对我没有帮助。

编辑:另外,这是个好主意吗?还是有更好的方法来实现这一点?

4

2 回答 2

9

该标准不保证调用谓词的顺序。

你应该使用的是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));
}
于 2016-08-08T23:00:25.117 回答
-1

它们应该按顺序处理,但不能保证

std::remove_if()erase()将“已移除”的项目移动到容器的末尾,直到被调用,它们才真正从容器中移除。这两个操作都可能使std::vector.

于 2016-08-08T23:02:32.213 回答