我使用std::erase_if
和一个计数器来删除容器中的一半元素,代码如下。使用gcc10
编译C++20。
#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;
}
}
输出结果出乎意料。对于向量,多了一个元素被删除:10
4
10
5
10
5
我打印出结果发现 vector[1]
是被意外移除的元素
尽管这通常不是erase_if的正常用法,但我仍然很好奇为什么它只发生在vector而不是其他的map上。我猜这可能与迭代器类型有关。如果有人能给出详细的解释,我将不胜感激。
static unsigned i = 0;
添加到lambda中,则可以正常工作。很奇怪,当在不同的算法中使用时,它的行为是不同的。我猜测gcc复制了lambda并在std::erase_if(vector)
中使用了一次。@AdrianMole 是的,我在VS2022中也遇到了相同的问题。 - Ted Lyngmoregular_invocable
概念,这意味着相同的输入可能会产生不同的结果。我严重怀疑在将其用作谓词时会导致未定义行为。 - 康桓瑋