std :: multiset是否保证插入顺序?

时间:2010-04-15 07:40:53

标签: c++ stl data-structures standard-library

我有std::multiset存储class A的元素。我为这个课提供了自己的operator<实现。我的问题是,如果我在这个multiset中插入两个等效对象,他们的顺序是否有保证?例如,首先我将对象a1插入到集合中,然后将等效对象a2插入到此集合中。当我遍历集合时,我可以期望a1a2之前到来吗?如果不是,有没有办法用multiset来实现这个目标?

3 个答案:

答案 0 :(得分:21)

在C ++ 03中,我们无法保证inserterase保留相对排序。但是,这在C ++ 0x中发生了变化:

  

n3092,§23.2.4/ 4:关联容器支持唯一键,如果每个键最多可包含一个元素。否则,它支持等效键。 set和map类支持唯一键; multiset和multimap类支持等效键。 对于multiset和multimap,insert和erase保留等效元素的相对顺序。 强调我的。

这在defect report中讨论。 This page是关于这个问题的评论集合,它写得很好并且非常充实。 (我非常建议您在之前的“概述”链接中阅读此内容。)

在该评论页面中,您将找到当前实施的比较,因此您可以检查您打算使用的实施是否符合您的预期。

我想不出一种强迫你想要的排序的方法。 :/

答案 1 :(得分:3)

考虑到a1a2在您的示例中比较相等,std::multiset中实际存储的内容是a1和{{1}的副本我真的不知道你怎么知道哪个是哪个。

如果你能说出不同之处,那么a2可能并非设计得很好。所以class A并不保证这样的事情。

答案 2 :(得分:1)

std :: multimap不保证这一点。 如果您可以通过函数使用整数来表达operator<,例如int A::orderingInt(),您可以使用

std::multiset<MyCustom> myset;

class MyCustom : public std::vector<A> {}

重载

bool operator<(const MyCustom& a, const MyCustom& b) {
   // theoretically empty MyCustom should not occure
   return a[0].orderingInt() < b[0].orderingInt();
}

当然,添加和迭代现在会有所不同:

A a;
myset[a.orderingInt()].push_back(a);

// groups with "small" elements first
for(std::multiset<MyCustom>::iterator it=myset.begin(); it!=myset.end(); it++) {
    // those elements are "equal"
    for(std::vector<A>::iterator jt=it->begin(); jt->end(); jt++) { 
         // use A& a = *jt;
    }
}