2016-11-13 7 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。グラムの++といえ打ち鳴らす++で

は、私は、要素の順序は呼び出しの間を保存されなかったことを示していると思われる

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以降のみです。 –

関連する問題