简体   繁体   English

C ++ stl unordered_map实现,引用有效性

[英]C++ stl unordered_map implementation, reference validity

For both std::map and std::tr1::unordered_map , I see from the standard that: 对于std::mapstd::tr1::unordered_map ,我从标准中看到:

References to elements in the unordered_map container remain valid in all cases, even after a rehash. 在所有情况下,对unordered_map容器中元素的引用仍然有效,即使在重新散列之后也是如此。

How are they doing that ( implementation-wise )? 他们是如何做到的(以实施方式 )? Are they maintaining all the entries as a kind of linked list and then the hash-table just stores pointers to the elements? 他们是否将所有条目都维护为一种链表,然后哈希表只存储指向元素的指针?

Yes, linked lists are involved, although not quite in the way you suggest. 是的,涉及链接列表,尽管不像你建议的那样。

The 2011 standard says (23.2.5 para 8), "The elements of an unordered associative container are organized into buckets. Keys with the same hash code appear in the same bucket." 2011标准说(23.2.5第8段),“无序关联容器的元素被组织成桶。具有相同哈希码的密钥出现在同一个桶中。”

Within each bucket, the elements are in a linked list (a separate list for each bucket, not one big list for the whole container). 在每个存储桶中,元素位于链接列表中(每个存储桶的单独列表,而不是整个容器的一个大列表)。 When the container is rehashed, the elements will be assigned to new buckets, but the pointers to each element remain valid. 当容器被重新散列时,元素将被分配给新的桶,但是指向每个元素的指针仍然有效。 The linked list in each new bucket is assembled from pointers to the existing elements that end up in that bucket. 每个新存储桶中的链接列表都是从指向最终存储在该存储桶中的现有元素的指针组合而成。

Iterators are invalidated by a rehash, since an iterator needs to hold pointers to both the element and its bucket (so it can be stepped from the last element of one bucket to the first element of the next). 迭代器由于重新散列而失效,因为迭代器需要保持指向元素及其桶的指针(因此它可以从一个桶的最后一个元素步进到下一个桶的第一个元素)。 The element pointer remains valid, so existing pointers and references to an element are still valid, but the bucket pointer is invalidated by a rehash, so the iterator isn't usable. 元素指针保持有效,因此现有指针和对元素的引用仍然有效,但是桶指针由rehash无效,因此迭代器不可用。

(This is also why unordered containers only support forward iterators, instead of the bidirectional iterators supported by the ordered associative containers. The elements of each bucket are in a singly linked list, so you can't step backwards through them.) (这也是无序容器只支持前向迭代器而不是有序关联容器支持的双向迭代器的原因。每个桶的元素都在一个单独的链表中,所以你不能倒退它们。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM