std::remove_if 将“const type”作为“this”参数传递会丢弃 linux 上的限定符 [重复]
Posted
技术标签:
【中文标题】std::remove_if 将“const type”作为“this”参数传递会丢弃 linux 上的限定符 [重复]【英文标题】:std::remove_if passing ‘const type’ as ‘this’ argument discards qualifiers on linux [duplicate] 【发布时间】:2017-10-20 12:54:46 【问题描述】:由于我昨天的post 被否决了,再次在这里,仅提供最简单的示例和我的问题。
#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 上?我了解如何自己解决问题,但由于这是外部代码,如果没有必要,我不想编辑代码本身。
【问题讨论】:
您昨天的帖子不仅被否决(实际上不必担心),而且还被标记为重复。你读过副本吗? 同样被否决是没有理由再次发布相同的问题......并且在第一句话中提到它不会阻止你再次被否决(实际上我希望正好相反) 是的,它被标记为重复,通读重复并不能回答我的问题:为什么它在 Windows 上有效,但在 Linux 上无效。我明白为什么它不起作用,它不应该起作用以及如何修复它,问题是它仍然可以在 Windows 机器上运行,没有任何解释 “不起作用”/“确实起作用”一般来说有点太模糊了。如果您违反 c++ 中的规则,那么“似乎可以工作”是可能的结果。既然已经知道它是错误的,为什么还想知道它为什么在 Windows 上“有效”? 原因是,我正在使用在 Windows 上开发的同事的代码库,他不想更改代码库。如果我能解释为什么我们需要改变这一点,那将使这个论点变得容易得多。此外,我只是对这种情况下的内部结构感到好奇。 【参考方案1】:std::remove_if
不适用于多重集。它仅适用于可以重新排序的容器,因为要删除的元素会被其他填补空白的元素临时覆盖。
使用multiset
,您不能覆盖给定迭代器的值,因为迭代器是定义的排序函数和当前内容的乘积。
如果这适用于 MSVC,那么 STL 实现的功能超出了标准的要求。依赖它是不安全的,因为不能保证。
【讨论】:
所以我应该将其视为 MSVC 的“错误”? @mimre 这不一定是一个错误,在这种情况下我的猜测是它是未指定的行为,并且允许实现比标准要求的更多以上是关于std::remove_if 将“const type”作为“this”参数传递会丢弃 linux 上的限定符 [重复]的主要内容,如果未能解决你的问题,请参考以下文章