简体   繁体   English

unordered_set :: erase(pos)是否保留元素的顺序?

[英]Does unordered_set::erase(pos) preserve the order of elements?

I read in the standard of C++14 that the order of elements is preserved when using erase(iterator pos) of unordered_set . 我在C ++ 14的标准中读到,当使用unordered_set erase(iterator pos)时,元素的顺序得以保留。

I tried the following code with g++-6.2.0 and clang-3.9 (on linux though, this gcc's stdlib). 我用g ++-6.2.0和clang-3.9尝试了以下代码(尽管在Linux上,此gcc的stdlib)。 Both should be able to handle that by the C++14-spec, I think: 我认为,两者都应该能够通过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
}

Yes, the order of the elements is arbitrary. 是的,元素的顺序是任意的。 Here MSVC++ 19.00 had 9 1 2 3 4 5 6 7 8 10 . 在这里MSVC ++ 19.00具有9 1 2 3 4 5 6 7 8 10 And after erasing all even elements the remaining elements are still in the same order 9 1 3 5 7 . 在擦除所有偶数元素之后,其余元素仍保持相同的顺序9 1 3 5 7

With g++ and clang++ though, I got a completely bad output of 但是使用g ++和clang ++时,我得到的输出完全不好

10 9 8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2 1

which seems to indicate that the order of the elements was not preserved between calls but just... I don't know. 这似乎表明元素的顺序在两次调用之间并未保留 ,而只是...我不知道。

What is going on? 到底是怎么回事?

I suppose that this cycle is wrong: 我认为这个周期是错误的:

for(auto it = nums.begin(); it!=nums.end(); ++it) {
    if(*it % 2 == 0) {
        nums.erase(it);
    }
}

If erase is performed then it is invalidated and you cannot increment it. 如果执行擦除操作,则操作无效,并且您无法递增。 Presumably it causes the aforementioned behaviour. 据推测,这会导致上述行为。

You should use something like this: 您应该使用这样的东西:

for(auto it = nums.begin(); it!=nums.end();) {
    if(*it % 2 == 0) {
        nums.erase(it++);
    } else {
        ++it;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM