2017-10-20 84 views
0

預選賽由於我post從昨天開始認真評選,在這裏再次,只有最小的例子,我的問題。的std ::傳遞的remove_if「常數類型」爲「本」的說法丟棄在Linux上

#include <set> 
#include <algorithm> 
using namespace std; 

class dummy 
{ 
public: 
    dummy(int x) 
     : test(x) 
    {} 

    bool operator()(const int &a) const 
    { 
    return false; 
    } 

protected: 
    int test; 
}; 


void foo() 
{ 

    // Determine the bounding box. 
    multiset<float> test; 
    test.insert(3.5); 
    multiset<float>::iterator itVertex = test.begin(); 


    multiset<int> workset; 
    workset.insert(3); 

    for (itVertex = test.begin(); itVertex != test.end(); itVertex++) 
    { 
    multiset<int>::iterator itEnd = remove_if(workset.begin(), workset.end(), dummy(3)); 

    } 
} 

我測試過的兩臺機器的例子:在Linux(Ubuntu的16.04,G ++ 5和6)我得到的前面描述的錯誤:

/usr/include/c++/5/bits/stl_algo.h:868:23: error: assignment of read-only location ‘__result.std::_Rb_tree_const_iterator<_Tp>::operator*()’ __result = _GLIBCXX_MOVE(__first);

在Windows 7的Visual Studio 2008年,編譯好。

我也檢查了複製,但他們失敗來形容它上的Windows工作,但確實不 Linux的情況。

那麼爲什麼它在Windows上編譯得很好呢?爲什麼不在Linux上?我瞭解我如何解決問題本身,但由於這是外部代碼,如果不是必要,我不想編輯代碼本身。

+1

昨日從您的文章不僅downvoted(其實不是洙多操心),但它被標記爲重複。你讀過重複嗎? – user463035818

+0

也正在downvoted沒有理由再次發佈了同樣的問題......並且提到它在第一個句子不會阻止你再次獲得downvotes(實際上可以我想到適得其反) – user463035818

+0

是的,它被認定爲重複,並通過閱讀重複不會給我的問題的答案:爲什麼它可以在Windows上運行,但不能在Linux上運行。 我明白爲什麼它不工作,並且它不應該工作以及如何解決它的問題是,它仍然工作在Windows機器上沒有任何解釋 – mimre

回答

1

std::remove_if不以多集工作。它只適用於可重新排序的容器,因爲要移除的元素會被其他可填補空白的元素暫時覆蓋。

對於multiset,由於迭代器是定義的排序函數和當前內容的乘積,因此無法覆蓋給定迭代器的值。

如果這一點也適用MSVC,那麼STL實現做超過標準要求。不安全的依賴,因爲它不能保證。

+0

所以我應該把它看作是MSVC的一個「bug」? – mimre

+0

@mimre它不是一個錯誤,我在這種情況下的猜測是它是未指定的行爲,並且實現允許做比標準任務更多的操作 – user463035818

相關問題