unordered_set::erase(pos)是否保留元素的顺序?
Does unordered_set::erase(pos) preserve the order of elements?
我在c++ 14的标准中读到,当使用unordered_set
的erase(iterator pos)
时,元素的顺序是保留的。
我用g++-6.2.0和clang-3.9(在linux上,这个gcc的stdlib)尝试了下面的代码。我认为两者都应该能够在c++ 14规范中处理这个问题:
#include <unordered_set>
#include <iostream>
using std::unordered_set; using std::cout;
// output
template<typename Elem, typename Comp>
std::ostream& operator<<(std::ostream&os, const unordered_set<Elem,Comp>&data) {
for(auto &e : data) { os << e << ' '; } return os << 'n'; }
int main() {
unordered_set<int> nums{ 1,2,3,4,5,6,7,8,9,10 };
cout << nums; // MSVC: 9 1 2 3 4 5 6 7 8 10
for(auto it = nums.begin(); it!=nums.end(); ++it) {
if(*it % 2 == 0) {
nums.erase(it);
}
}
cout << nums; // MSCV: 9 1 3 5 7
}
是的,元素的顺序是任意的。这里msvc++ 19.00有9 1 2 3 4 5 6 7 8 10
。并且在擦除所有偶数元素后,剩下的元素仍然是相同的顺序9 1 3 5 7
。
使用g++和clang++,我得到了一个完全糟糕的输出
10 9 8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2 1
,这似乎表明元素的顺序在调用之间没有保留,而只是…我不知道。
怎么回事?
我想这个循环是错误的:
for(auto it = nums.begin(); it!=nums.end(); ++it) {
if(*it % 2 == 0) {
nums.erase(it);
}
}
如果执行erase,则it无效且不能递增。可能会导致上述行为。
你应该这样写:
for(auto it = nums.begin(); it!=nums.end();) {
if(*it % 2 == 0) {
nums.erase(it++);
} else {
++it;
}
}
相关文章:
- 即使在使用 delete[] 后仍保留的元素
- 调用QVector::保留即使不知道确切的元素数量?
- 在数组的开头添加一个元素并移动其余元素,但保留大小
- 保留从一个多集复制到另一个多集的元素的顺序
- 引用保留向量中的第一个元素
- 使用 STL 仅保留 N 个最小元素(带有重复项)
- 单独保留重复元素
- 仅保留给定列表中不重复的元素.例如:(a b a a a c c) 给我们 (a b)
- 自定义容器在保留空间时不必要地创建新元素实例
- 在向量 (C++) 中保留插入元素的地址
- 将元素保留在动态数组中
- 矢量元素如何在矢量 std::move 之后保留其原始地址
- 保留 std::vector 的前 N 个元素<>并删除其余元素
- 组合两个矩阵,保留其元素值
- 分配给尚未调整大小但保留的向量元素,称为合法
- 如何在不初始化每个元素的情况下为数组保留空间
- 将最小的n个元素保留在集合中,丢弃其他元素
- 对容器进行排序,然后在保留原始排序的情况下移动元素
- unordered_set::erase(pos)是否保留元素的顺序?
- 我如何构建公共数据,同时保留默认的移动元素和分配