2017-10-20 83 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

相关问题