std::remove_if 将“const type”作为“this”参数传递会丢弃 Linux 上的限定符

std::remove_if passing ‘const type’ as ‘this’ argument discards qualifiers on linux

本文关键字:Linux 作为 if remove const this std type 参数传递      更新时间:2023-10-16

由于我昨天的帖子被投票了,这里再次,只有最少的例子和我的问题。

#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:错误:分配只读位置"__result.std::_Rb_tree_const_iterator<_Tp>::operator*()" __result = _GLIBCXX_MOVE(__first);

在Windows 7 Visual Studio 2008上,它可以很好地编译。

我也检查了重复项,但它们无法描述它在Windows工作但在Linux不起作用的情况。

那么为什么它在Windows上编译得很好呢?为什么不在 Linux 上呢?我了解如何解决问题本身,但由于这是外部代码,如果没有必要,我不想编辑代码本身。

std::remove_if不适用于

多集。它仅适用于可以重新排序的容器,因为要删除的元素会暂时被其他可以填补空白的元素覆盖。

使用 multiset ,您不能覆盖给定迭代器的值,因为迭代器是定义的排序函数和当前内容的乘积。

如果这适用于 MSVC,那么 STL 实现的作用超出了标准要求。依靠它不安全,因为它不能保证。