2017-10-20 7 views
0

昨日の私のpostが投票しました。ここでも最小限の例と私の質問で投票しました。std :: remove_if 'this'の引数として 'const type'を渡すと、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)); 

    } 
} 

は、私は2台のマシン上の例をテストしてみた:Linux上で(Ubuntuの16.04、G ++ 5及び6)私は、前述のエラーが表示されます。

のWindows 7のVisual Studio 2008のそれをオン

/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のに動作しますが、Linuxないを行いケースを記述するために失敗します。

なぜWindows上でうまくコンパイルできますか?なぜLinux上ではないのですか?どのようにして問題を解決できるのか理解していますが、これは外部コードなので、必要でない場合はコード自体を編集したくありません。

+1

あなたの投稿は昨日からだけでなく、実際には心配していませんでしたが、重複としてフラグが立てられました。あなたは重複を読んだのですか? – user463035818

+0

また、同じ質問を再度投稿する理由はありません...そして、最初の文章でそれを言及することは、あなたがダウンワードをもう一度得ることを妨げないでしょう。(事実、私はちょうど反対です) – user463035818

+0

はい、それは重複としてフラグが立てられ、重複は私の質問に答えることはできません:Windowsでは動作しますがLinuxでは動作しないのはなぜですか? なぜ動作しないのか、動作してはいけないとわかる方法を理解していますが、Windowsマシンでは何も説明せずに動作します。 – mimre

答えて

1

std::remove_ifはマルチセットでは機能しません。除去されるべき要素がギャップを埋める他の要素によって一時的に上書きされるので、それは並べ替え可能なコンテナでのみ機能する。

multisetの場合、イテレータは定義されたソート関数と現在のコンテンツの積であるため、指定したイテレータの値をオーバーライドすることはできません。

これがMSVCで動作する場合、そのSTL実装は標準よりも多くの処理を行っています。それが保証されていないので、それに頼るのは安全ではありません。

+0

これをMSVCの「バグ」と考えるべきでしょうか? – mimre

+0

@mimreこれはバグではありませんが、この場合の私の推測は、それが不特定の動作であり、実装が標準の命令よりも多くを行うことが許可されていることです – user463035818

関連する問題