对于std::map
和std::tr1::unordered_map
,我从标准中看到:
对unordered_map容器中元素的引用仍然有效 所有情况,即使经过重新训练。
他们是如何做到的(实施方式)?他们是否将所有条目作为一种链表保存,然后哈希表只存储指向元素的指针?
答案 0 :(得分:24)
是的,涉及到链接列表,但并不像你建议的那样。
2011标准说(23.2.5第8段),“无序关联容器的元素被组织成桶。具有相同哈希码的密钥出现在同一个桶中。”
在每个存储桶中,元素位于链接列表中(每个存储桶的单独列表,而不是整个容器的一个大列表)。当容器被重新散列时,元素将被分配给新的桶,但是指向每个元素的指针仍然有效。每个新存储桶中的链接列表都是从指向最终存储在该存储桶中的现有元素的指针组合而成。
迭代器使迭代器失效,因为迭代器需要保持指向元素及其存储桶的指针(因此它可以从一个存储桶的最后一个元素步进到下一个存储区的第一个元素)。元素指针保持有效,因此现有指针和对元素的引用仍然有效,但是桶指针由rehash无效,因此迭代器不可用。
(这也是无序容器仅支持前向迭代器而不是有序关联容器支持的双向迭代器的原因。每个桶的元素都在单个链表中,因此您不能向后退一步。)