4

I wrote some code like this:

unordered_map<int, int> uii;
uii.insert(make_pair(12,4));
uii.insert(make_pair(3,2));
uii.insert(make_pair(6,1));
uii.insert(make_pair(16,9));
....

When I use a for loop to visit this map, it prints key in the right order of my insertion. I tested unordered_set, with same result.

So my question is, does the C++ standard guarantee the visiting order as insert order, just like Java's LinkedHashMap?

Pika Supports Ukraine
  • 3,612
  • 10
  • 26
  • 42
Troskyvs
  • 7,537
  • 7
  • 47
  • 115
  • 3
    It is unordered. – Yola Nov 20 '18 at 09:21
  • 6
    [*"Internally, the elements are not sorted in any particular order, but organized into buckets. Which bucket an element is placed into depends entirely on the hash of its key."*](https://en.cppreference.com/w/cpp/container/unordered_map) – HolyBlackCat Nov 20 '18 at 09:23
  • Since it's trivial to reorder your four insert statements and see whether the loop _still_ visits in insert order ... did you do this? – Useless Nov 20 '18 at 09:54
  • This is a [counterexample](http://coliru.stacked-crooked.com/a/13f2b9548f32cf69), the output is out of order due to rehash. – felix Nov 20 '18 at 10:20
  • unordered_map is analogous to HashMap not LinkedHashMap. – Paul Rooney Nov 20 '18 at 10:47

1 Answers1

7

No, it is unordered, there is no such guarantee.

Elements in an unordered associative container are organized into buckets, keys with the same hash will end up in the same bucket. The number of buckets is increased when the size of the container increases to keep the average number of elements in each bucket under a certain value.

Rehashing invalidates iterator and might cause the elements to be re-arranged in different buckets but it doesn't invalidate references to the elements.

This is valid for both unordered_map and unordered_set.

You might also want to check this question Keep the order of unordered_map as we insert a new key


But, internally an implementation of unordered container might use list or other ordered container to store elements and store only references to sublists in its buckets, that would make iteration order to coincide with the insertion order until enough elements are inserted to cause list rearranging. That is the case with VS implementation.

Yola
  • 18,496
  • 11
  • 65
  • 106
  • The ordered bucket container will preserve insertion order _if all the elements end up in the same bucket_, but not otherwise. – Useless Nov 20 '18 at 09:56
  • @Useless sorry, i couldn't find such a requirement, and i believe in case of rehashing this doesn't hold. – Yola Nov 20 '18 at 10:06
  • Oh, I read your last section as asserting that an ordered bucket container would give you insertion-ordered traversal. You're actually saying some unordered implementations have an insertion-ordered underlying store and only hash references into it? – Useless Nov 20 '18 at 10:11
  • 1
    Yes, but every bucket has its own part of this underlying container. One need to insert enough elements to cause underlying container (list) to rearrange -- to move the front element somewhere in the middle of the list where its bucket belongs. – Yola Nov 20 '18 at 10:21
  • @Useless i updated the post, thanks for pointing out this mistake. – Yola Nov 20 '18 at 10:23
  • That's one weird-sounding hash table design. I should read up on it and find out what it's good for. – Useless Nov 20 '18 at 10:37