2016-11-13 8 views
0

erase(iterator pos)unordered_set으로 사용할 때 요소의 순서가 유지된다는 것을 C++ 14의 표준에서 읽었습니다.unordered_set :: erase (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의 ++ 및하지만 그 소리 ++와

, 나는 요소의 순서가 호출 사이 보존되지 않았 음을 나타내는 것

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

완전히 잘못된 출력을 가지고 있지만, 그냥 ... 내가하지 알고있다.

무슨 일입니까?

+0

표준 텍스트의 1000 페이지가 있습니다. 당신이 표준에서 그것을 읽었다 고 말하는 것은 유용하지 않습니다. 표준에서 어디서 읽었습니까? – hvd

답변

3

나는이주기가 잘못되었다는 가정 : 그것은가 무효화

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

삭제경우 다음을 수행하고 당신이 그것을 증가 수 없습니다. 아마도 그것은 앞에서 언급 한 행동을 유발합니다.

는이 같은 것을 사용해야합니다

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

아! 예 물론! – towi

+0

아니면 그냥 '지우기'의 반환 값을 사용할 수 있습니다. –

+0

@JesperJuhl은 C++ 11 이후입니다. –