【发布时间】:2013-11-01 15:13:05
【问题描述】:
我有一张存储<int, char *> 的地图。现在我想按插入的顺序检索元素。 std::map 改为返回按键排序的元素。有可能吗?
【问题讨论】:
我有一张存储<int, char *> 的地图。现在我想按插入的顺序检索元素。 std::map 改为返回按键排序的元素。有可能吗?
【问题讨论】:
如果你不关心基于int的顺序(IOW你只需要插入顺序而不关心正常的密钥访问),只需将其更改为vector<pair<int, char*>>,即由按插入顺序排序的定义(假设您只在末尾插入)。
如果您想同时拥有两个索引,则需要 Boost.MultiIndex 或类似的东西。不过,您可能需要保留一个只会向上计数的单独变量(将是一个稳定的计数器),因为只有当您从未从地图中删除任何内容时,您才能使用 .size()+1 作为新的“插入时间键”。
【讨论】:
现在我想按插入的顺序检索元素。 [...] 有可能吗?
不,不是std::map。 std::map 将元素对插入到一个已经排序的树结构中(在插入操作之后,std::map 无法知道每个条目是何时添加的)。
您可以通过多种方式解决此问题:
使用std::vector<std::pair<int,char*>>。这将起作用,但不能提供地图所做的自动排序。
使用 Boost 的东西(@BartekBanachewicz 建议使用 Boost.MultiIndex)
使用两个容器并保持它们同步:一个使用顺序插入(例如std::vector),另一个使用键索引(例如std::map)。
自己使用/编写自定义容器,以便支持两种类型的索引(按键和插入顺序)。除非您有非常具体的要求并且经常使用它,否则您可能不需要这样做。
【讨论】:
几个选项(Bartek 建议的选项除外):
如果您仍然想要基于键的访问,您可以使用映射以及包含所有键的向量,按插入顺序排列。但是,如果您想稍后删除元素,这将变得低效。
** 最好存储映射迭代器,但这会导致循环定义问题。
【讨论】: