4

If I have the following piece of code

std::unordered_multimap<std::string, std::vector<double>> myMap;
std::vector<double> v1, v2, v3;
// init v1, v2, v3....
myMap.insert(std::make_pair<std::string, std::vector<double>("vec", v1));
myMap.insert(std::make_pair<std::string, std::vector<double>("vec", v2));
myMap.insert(std::make_pair<std::string, std::vector<double>("vec", v3));

If I access the values with an iterator they will always be in this order: v1, v2, v3

So basically if I insert elements of the same key, but different value, do they always retain the order of insertion?

djWann
  • 2,017
  • 4
  • 31
  • 36
  • 3
    The best way to use an unordered container is to not consider the order at all. Not rely on the order at all. If you're looking at the order of the elements for some reason, you are probably using the wrong container. There's no guarantee it will retain insertion order. – goji Jan 15 '13 at 20:43
  • @Troy Can I use std::multimap instead? – djWann Jan 15 '13 at 20:48
  • 2
    If you need insertion order in an asociative container, you'll probably need something like boost's multi_index. There's other questions about this on SO. – goji Jan 15 '13 at 20:58

3 Answers3

7

I guess this is implementation specific. In an unordered_multimap elements with same key are stored in the same bucket if the implementation is a bucket hash map, in this case they could be in the same order of insertion (that is probably your situation).

But in an unordered_map implemented, for example, with an open addressing technique, the order could change. I don't know if there are STL implementations which uses different under the hood implementation but the contract of the class doesn't make any assumption on the order of the values for the same key so I don't think you can take it for granted.

Taken from here:

Internally, the elements in the unordered_map are not sorted in any particular order with respect to either their key or mapped values

Jack
  • 131,802
  • 30
  • 241
  • 343
  • In order to maintain the order of insertion can I use a simple multimap? – djWann Jan 15 '13 at 20:47
  • 1
    Either with an `unordered_multimap` there are no guarantees of order of values, maybe under 90% of implementations it will work but it is not granted in any case. – Jack Jan 15 '13 at 20:50
  • Sorry I was referring to std::multimap not std::unordered_multimap – djWann Jan 15 '13 at 20:52
  • You can keep any order if instead of `std::unordered_multimap` you use `std::unordered_map>` – Csq Jan 15 '13 at 20:52
  • 2
    The order of elements with the same key must be ordered. This is in order to implement [equal_range](http://en.cppreference.com/w/cpp/container/unordered_map/equal_range). [MSDN](http://msdn.microsoft.com/en-us/library/bb982522.aspx) also says: `You can always be assured, however, that any subset of elements that have equivalent ordering are adjacent in the controlled sequence.`. – Jesse Good Jan 15 '13 at 20:53
  • 3
    @djWann: I should clarify that it is not a total order, just that elements with the same value are adjacent. – Jesse Good Jan 15 '13 at 21:05
4

The whole point of "unordered" in the name is that you can't rely on the order. Ever.

If you detect any order coming from iterating the container, it's a coincidence or an artifact of the implementation. You should never count on it.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
3

Unless the documentation says that they'll always be returned in insertion order, you would be doing the wrong thing to rely on it. The STL implementation you use today could change. It also might be the case that the implementation you're using would work differently if there were a lot of entries in the map.

J.Merrill
  • 1,233
  • 14
  • 27