how does the stl's multimap insert respect orderings?

后端 未结 7 2137
灰色年华
灰色年华 2020-12-03 21:15

I have some data which come with a integer index. I am continuous generating new data which needs to added to the collection of data I have, sorted by that index, at the sa

相关标签:
7条回答
  • 2020-12-03 21:21

    It sounds like multimap is what you need...

    However, I also need data with the same index to be kept in the order in which it was inserted, in this case meaning that when I iterate through the data I get to the earlier data before the later data.

    It will be in the order of the index. If the index increases over time as you insert more items, then yes because of the nature of your index, the "earlier" data will come first.

    Otherwise, no. You could keep two multimaps to the same data. One kept in order of index, the other in order of insertion time:

    std::multimap<index, T*> orderedByIndex;
    std::multimap<time, T*> orderedByInsertionTime;
    

    Giving you the ability to iterate the map both ways.

    (Edit I'm reading this to mean you want to sometimes iterate by index or sometimes iterate by insertion time, but see the above answer if you mean first index then insertion time.)

    0 讨论(0)
  • 2020-12-03 21:31

    The elements that belongs to the same key is ordened by lower_bound and upper_bound functions when you retrieve the information, therefore you don't have the guarantee that you will access (by equal_range) the elements in the order that they were inserted.

    0 讨论(0)
  • 2020-12-03 21:32

    Unless I've missed something, the standard doesn't provide any such guarantee.

    The most obvious workaround would be to include a sequence number as a secondary key. For example, in your class include a static unsigned long, and each time you create an object to insert in the multimap, put its current value into your object, and increment it. In your object's comparison function, use that counter as the deciding factor for ordering if the data you're currently using as the key compares equal. Note that in this case, each key will be unique, so you can use a map instead of a multimap.

    0 讨论(0)
  • 2020-12-03 21:34

    It seems the new standard (C++11) changed this:

    The order of the key-value pairs whose keys compare equivalent is the order of insertion and does not change.[cppreference]

    I'm hesitating to use it though, as this seems like a detail easily overlooked when modifying the standard library to be C++11 compliant and it's the sort of detail that will silently cause errors if your compiler's library failed to implement properly.

    0 讨论(0)
  • 2020-12-03 21:37

    Boost multi_index supports what you are trying to do, if you don't want to take the workaround given by Jerry Coffin.

    0 讨论(0)
  • 2020-12-03 21:44

    If I got you right - you need the data sorted by some key. Whenever you insert 2 things with the same key, you need to retrieve them in the order of insertion.

    If that's the case, then you have to take a look at the implementation of your multimap. Depending on how it handles the case of multiple insertions with the same key it may or may not have this guarantee. I guess the standard does not offer this kind of guarantee, since it would limit the implementation for a very special case.

    Another approach is to go for a Map (not Multi) and create a compound key. The key consists of the normal key you choose and an alway increasing counter. On comparison, with equal keys, the insertion number makes the key unique. This way you force unique keys and the order on equal "normal" keys (I hope this was understandable).

    I guess the last approach is the easiest to implement.


    Option: (not preferable)

    You can always go for a self-made datastructure with this guarantee. I'd go for a Tree (Red-Black or AVL for example) with a vector to hold the inserted data. On iteration you have to find the node, go to the vector and iterate on it's content. Whenever you finish with the vector, you continue with the next node.

    0 讨论(0)
提交回复
热议问题