Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can we store unordered_map<T>::iterator?

Tags:

c++

Reference http://www.careercup.com/question?id=17188673 by chetan.j9

void Insert( string s ) {
    if( IsElementPresent(s) )
        return;

    myMap[s] = myMapVector.size();
    unordered_map<string,int>::iterator it = myMap.find(s);
    myMapVector.push_back(it);      
}

Question> Can we store the iterator of unordered_map for later retrieval? Based on my understanding, the iterator will be invalidated after the insertion or deletion of an element.

Thank you

like image 341
q0987 Avatar asked May 27 '13 23:05

q0987


Video Answer


2 Answers

@syam's answer is correct (+1), but I think it's useful to quote from the only authoritative source, the C++11 Standard:

(§23.2.5/13) The insert and emplace members shall not affect the validity of references to container elements, but may invalidate all iterators to the container. The erase members shall invalidate only iterators and references to the erased elements.

(§23.2.5/14) The insert and emplace members shall not affect the validity of iterators if (N+n) < z * B, where N is the number of elements in the container prior to the insert operation, n is the number of elements inserted, B is the container’s bucket count, and z is the container’s maximum load factor.

(To put this in context: §23.2.5 is the section on unordered associative containers, so it applies to std::unordered_set, std::unordered_map, std::unordered_multiset and std::unordered_multimap.) This means:

  1. If you want to insert n elements into an unordered_map called hash, you can check whether

     hash.size() + n < hash.max_load_factor() * hash.bucket_count()
    

    is true. If it is false, all iterators will be invalidated during the insert. If true, iterators will remain valid.

  2. Even if iterators are invalidated in this operation, references to the elements themselves will remain valid.

  3. If you erase elements, only iterators pointing to those will be invalidated; other iterators will remain valid.

like image 86
jogojapan Avatar answered Nov 07 '22 04:11

jogojapan


Insertion of an item invalidates all iterators only if a rehashing occurs (ie. if the new number of elements is greater than or equal to max_load_factor()*bucket_count()). Otherwise no iterators are invalidated.

Removal of an item only invalidates the iterators to the removed element(s) not to other unrelated elements.

Source: std::unordered_map::insert and std::unordered_map::erase.

Of course these rules apply only to std::unordered_map. Other containers may have different invalidation rules, it's up to you to look it up in the documentation.

like image 44
syam Avatar answered Nov 07 '22 05:11

syam