确保对象更改时重新排序多重集

时间:2010-09-03 18:08:33

标签: c++ stl multiset

我有一个带有自定义谓词函数的多集,例如multiset<MyClass *,MyCompFunc>,其中MyCompFunc查看MyClass对象的属性。在应用程序进行过程中,对象可能会以导致它们重新排序的方式发生变化。

当发生这种情况时,让多重集合重新排序的正确方法是什么?手动对其进行排序,或删除修改后的对象,更新它并重新插入?

4 个答案:

答案 0 :(得分:3)

通常是删除,更新和重新插入。事实上,其他任何东西至少暂时违反了集合/多集的主要不变量,这显然不是一件好事。

答案 1 :(得分:1)

我仍然找不到任何明确说明的内容,但如果你修改了一个键[*],那么例如你的比较器不满足25.3(严格弱顺序)的要求:

  

comp引发明确的关系   在确定的等价类上   通过等价

comp如果在不同时间为相同输入返回不同的值,则不是明确定义的关系。

在您的情况下,我认为修改MyClass的字段并不参与比较。

有趣的是,23.1.2 / 2表示,“每个关联容器都在Key上进行参数化,并且有一个排序关系比较,它会对Key的元素产生严格的弱排序(25.3)”。我认为我们可以认为比较器在Key对象上引入了严格的弱排序,它们是容器的元素,不一定是Key类型的所有对象。例如,如果Key是一个指针,那么我很确定编写一个取消引用它的比较器是好的,只要你不使用空指针作为键。同样的道理,我希望我们可以修改一个不在容器中的密钥。

[*]通过“修改”,我的意思是做任何用这个键和其他键改变比较器结果的东西。在这种情况下,你当然不会真正修改密钥本身(这只是一个指针值),但这就是我所说的。

答案 2 :(得分:0)

不要通过引用访问对象。复制它们,如果密钥更改,则重新插入它们。您可以使用观察者自动执行此操作。

答案 3 :(得分:0)

如果要更改对象的部分比较键,首先从集合中删除该项目,然后执行修改,然后将其添加回集合中。这样就可以避免破坏集合的不变量,因为集合并不是为了对密钥更改进行重新排序。