具有两个搜索条件的C ++关联容器

时间:2012-03-23 11:00:30

标签: c++ boost stl associative-array

我正在寻找一个容器来存储我的一个类的对象,叫做Link,它有一个成员变量:“std :: string linkID”。容器的尺寸可以高达数百万,因此更快速查找是更优选的。 1-Later我需要使用linkID查找容器 2 - 但是,由于某些原因,添加对象的顺序也很重要。

我已经浏览了矢量,列表,设置,地图......我将研究多路复用,多地图和提升多索引。但我想,作为C ++的新手,我仍然需要一些更有经验的观点来帮助我根据上述两个标准选择最佳容器。

谢谢 瓦赫德

3 个答案:

答案 0 :(得分:4)

对我来说,这看起来像是boost :: multi_index_container

的perfekt用例

你的类型声明应该与此类似(未经测试)

typedef multi_index_container<
    Link,
    indexed_by<
        sequenced<>,
        ordered_unique< member< Link, std::string, &Link::linkID> >,
        ordered_unique< member< Link, std::string, &Link::linkID_2 > >
    >
> LinkList;
LinkList s;
s.push_back(Link(...));

一般与Frerich Raabe发布的解决方案相同。但我认为可以减少陷阱,并且可能更加优化。 阅读boost页面上的tutorial,了解如何访问存储在s中的元素。

您的评论......

  

实际上,我正在开发一个已经存在的项目   使用std :: vector只存储元素(如你所指出的那样)   出)。所以我现在可以按原样使用'存储'向量,只需添加   你建议的地图?

这是不可能的。矢量迭代器保持无效。在向量中添加或删除元素时,它们可能会变为未定义。

答案 1 :(得分:2)

使用Boost Bimap听起来很完美。

答案 2 :(得分:1)

如果要查找链接的属性不经常更改,则可以选择std::list<Link>作为保存链接对象的主容器。然后,对于每个条件,您有一个std::map,它将值映射到指向列表的迭代器。 E.g。

typedef std::list<Link> LinkList;

LinkList links = ...;
std::map<std::string, LinkList::iterator> linkByName;
std::map<unsigned int, LinkList::iterator> linkByPopularity;

关于std::list的好处是它具有非常强大的迭代器失效保证(基本上,如果从列表中删除元素,则只有列表中的迭代器才会变为无效。)

为了让这些结构一致地更新,你可以把它全部包装成一个'LinkCollection'包装器。