我有这个代码:
set<int>::iterator new_end =
set_difference(set1.begin(), set1.end(),
set2.begin(), set2.end(),
set1.begin());
set1.erase(new_end, set1.end);
它在 Visual Studio 中编译并运行良好。然而,在一个上一个问题 https://stackoverflow.com/questions/908949/what-happens-when-you-modify-an-element-of-an-stdset,人们表示,一个set
的迭代器应该是const
。我在标准中没有看到类似的内容。有人可以告诉我它在哪里说的,或者这是否是明确定义的行为?
如果不是,请提供满足我需要的代码。有没有办法在不创建临时集的情况下执行此操作?
您的代码违反了几个不变量set_difference
。从第 420 页开始约苏蒂斯书 http://www.josuttis.com/libbook/:
- 调用者必须确保目标范围足够大或者使用插入迭代器。
- 目标范围不应与源范围重叠。
您试图写回第一组,这是不允许的。您需要在源范围以外的地方写入 - 为此我们可以使用第三组:
std::set<int> set3;
std::set_difference(set1.begin(), set1.end(),
set2.begin(), set2.end(),
std::inserter(set3, set3.begin()));
第二个参数std::inserter
是元素应插入位置的提示。不过,这只是一个提示,请放心,这些元素最终会出现在正确的位置。set3
最初是空的,所以begin()
这是我们能给出的唯一提示。
拨打电话后set_difference
, set3
将包含您尝试制作的内容set1
包含在您的原始代码中。您可以继续使用set3
or swap
它与set1
如果你更喜欢。
Update:
我不确定它的性能,但如果你只想从中删除所有元素set1
出现在set2
, 你可以试试:
for (std::set<int>::iterator i = set2.begin(); i != set2.end(); ++i)
{
set1.erase(*i);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)