std::erase_if 删除 std::vector 上的额外元素?

res*_*net 13 c++ c++20

我使用std::erase_if捕获的计数器从容器中删除一半元素,如下所示。C++20 编译为gcc10

#include <iostream>
#include <vector>
#include <map>
#include <unordered_map>

int main()
{
    {
        std::vector<int> container(10);
        std::cout << container.size() << std::endl;
        std::erase_if(container, [i = 0u](auto&&...) mutable { return i++ % 2 == 0; });
        std::cout << container.size() << std::endl;
    }
    std::cout << std::endl;
    {
        std::map<int, int> container;
        for (int i = 0; i < 10; i++) {
            container.emplace(i, i);
        }
        std::cout << container.size() << std::endl;
        std::erase_if(container, [i = 0u](auto&&...) mutable { return i++ % 2 == 0; });
        std::cout << container.size() << std::endl;
    }
    std::cout << std::endl;
    {
        std::unordered_map<int, int> container;
        for (int i = 0; i < 10; i++) {
            container.emplace(i, i);
        }
        std::cout << container.size() << std::endl;
        std::erase_if(container, [i = 0u](auto&&...) mutable { return i++ % 2 == 0; });
        std::cout << container.size() << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是意外的。对于向量,删除一个额外的元素:

10
4

10
5

10
5
Run Code Online (Sandbox Code Playgroud)

我打印出结果,看起来像是vector[1]意外删除的元素

当然,这通常不是擦除 if 的正常用法,但我仍然很好奇为什么它只发生在矢量而不是其他地图上。我猜这与迭代器类型恶作剧有关。如果有人能给出详细的解释,我们将不胜感激。

Nic*_*las 13

remove_if需要一个谓词。标准库要求谓词类型

给定一个指定与 相同对象u的类型(可能是 const)的泛左值,应是等于 的有效表达式。T*firstpred(u)pred(*first)

你的谓词改变了它的内部状态。因此,使用相同的元素调用它两次将产生不同的结果。这意味着它不满足谓词的要求。

因此,未定义的行为随之而来。