2016-11-13 37 views
0

我從C++ 14的標準中讀到,當使用unordered_seterase(iterator pos)時,元素的順序被保留。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

或者你可以使用'erase'的返回值。 –

+0

@JesperJuhl只有自C++ 11以來。 –

相關問題