是下面的代码使用std :: set" legal&quot ;? [英] Is the following code using std::set "legal"?

查看:166
本文介绍了是下面的代码使用std :: set" legal&quot ;?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个代码:

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中编译并运行良好。但是,在上一个问题中,人们表示 set 的迭代器应该是 const 。我在标准中没有看到这样的东西。有人可以告诉我它在哪里说,或者如果这是明确定义的行为?

It compiles and runs fine in visual studio. However, in a previous question, people stated that a set's iterators are supposed to be const. I don't see anything like that in the standard. Can someone tell me where it says that, or if this is well-defined behavior?

如果不是,请提供代码,我需要做的。有没有办法做到这一点,而不创建一个临时集?

If it's not, please provide code that does what I need. Is there a way to do this without creating a temporary set?

推荐答案

您的代码违反了一些不变量 set_difference 。从 Josuttis Book 的第420页起:

Your code violates a couple of the invariants for set_difference. From page 420 of the Josuttis Book:


  • 调用者必须确保目标范围足够大或使用插入迭代器。

  • 目标范围不应与源范围重叠。

您尝试回写第一个集合,这是不允许的。您需要编写除源范围以外的其他位置 - 我们可以使用第三组:

You're trying to write back over the first set, which is not allowed. You need to write someplace other than the source ranges - for that we can use a third set:

std::set<int> set3;
std::set_difference(set1.begin(), set1.end(),
                    set2.begin(), set2.end(),
                    std::inserter(set3, set3.begin()));

std :: insertionter的第二个参数是元素应插入的位置的提示。这只是一个提示,但是,放心,元素将最终在正确的地方。 set3 最初为空,因此 begin()是我们可以提供的唯一提示。

The second argument to std::inserter is a hint for where the elements should be inserted. It's only a hint, however, rest assured that the elements will end up in the right place. set3 is initially empty, so begin() is about the only hint we can give.

调用 set_difference 后, set3 将包含您尝试创建的 set1 包含在原始代码中。您可以使用 set1 继续使用 set3 swap 如果您愿意。

After the call to set_difference, set3 will contain what you tried to make set1 contain in your original code. You can go on using set3 or swap it with set1 if you prefer.

更新:

如果你只想删除 set2 中出现的 set1 中的所有元素,你可以尝试:

I'm not sure about the performance of this, but if you just want to remove all elements from set1 that appear in set2, you can try:

for (std::set<int>::iterator i = set2.begin(); i != set2.end(); ++i)
{
    set1.erase(*i);
}

这篇关于是下面的代码使用std :: set&quot; legal&quot ;?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆