2013-05-27 9 views
7

参考http://www.careercup.com/question?id=17188673 unordered_map <T> :: iteratorを格納できますか?

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);  
} 

chetan.j9の質問>私たちは、後の検索のためunordered_mapのイテレータを保存することができますか?私の理解に基づいて、イテレータは要素の挿入または削除後に無効になります。

は、アイテムの

+1

すべてのコンテナのイテレータの無効化については、http:// stackoverflowを参照してください。com/questions/6438086/iterator-invalidation-rules – JRG

答えて

5

挿入が再ハッシュが発生した場合にのみ(すなわち要素の新しい番号がより大きいかmax_load_factor()*bucket_count()と等しい場合)すべてのイテレータを無効にしていただきありがとうございます。それ以外の場合はイテレータは無効になりません。

アイテムを削除すると、削除された要素のイテレータのみが無効になり、他の無関係な要素には無効になります。

出典:std::unordered_map::insertおよびstd::unordered_map::erase

もちろん、これらの規則はstd::unordered_mapにのみ適用されます。他のコンテナには異なる無効化規則があるかもしれませんが、ドキュメント内でそれを調べるのはあなた次第です。 syamの答え@

+0

無効化がいつ起こるかわからないので、 'insert'の実装は正しくありません。右? – q0987

+0

@ q0987無効化がいつ発生するのかは実際にわかります(ルールはかなり明確です)。事前に最大アイテム数を知っていれば、あらかじめ[予約する](http://en.cppreference.com/w/cpp/container/unordered_map/reserve)しておくと、イテレータを安全に保存することができますその予約された最大値を超えない限り、挿入します。もちろん、アイテムを挿入している間は、他のストーリー全体の不明な数のアイテムを挿入し、イテレータを格納することは実際には悪い考えです。 – syam

+2

厳密に言えば、再ハッシングの条件は、新しい要素の数が与えられた式よりも大きいか、または浮動小数点数を話しているので、文の否定と否定をよく使うことです。 。 – jogojapan

14

は、(1)正しいですが、私はそれが唯一の信頼できるソースから引用すると便利だと思う、C++ 11標準:

(§23.2.5/ 13)insertおよびemplaceメンバーは、コンテナ要素への参照の有効性に影響を与えてはならないが、コンテナへのすべてのイテレータを無効にする可能性がある。消去メンバーは、イテレータと消去された要素への参照のみを無効にするものとする。

(§23.2.5/ 14)insertemplaceメンバーはイテレータの有効性に影響を及ぼさないものであれば(N + N)Nは、挿入操作の前に、容器内の要素の数である<のZ *のB、 、nは挿入された要素の数、Bはコンテナのバケット数、zはコンテナの最大負荷率です。

(コンテキストでこれを置くために:§23.2.5それはstd::unordered_setstd::unordered_mapstd::unordered_multisetstd::unordered_multimapに適用されますので、順不同連想コンテナ上のセクションです。) これが意味:

  1. の場合あなたは

    hash.size() + n < hash.max_load_factor() * hash.bucket_count() 
    
    かどうかを確認することができ、hashと呼ばれるunordered_mapn要素を挿入したいです210

    がtrueです。 falseの場合、すべてのイテレータは挿入時に無効になります。 trueの場合、イテレータは有効なままです。

  2. この操作でイテレータが無効になっても、要素自体に対する参照の参照は有効のままです。

  3. erase要素の場合は、その要素を指すイテレータのみが無効になります。他のイテレータは有効なままです。

+0

ポイント2を理解する上で問題があります。私に例を挙げてください。ありがとうございます。 – q0987

+1

@ q0987たとえば、ハッシュに格納されている値への参照を取得したとします。 'int&val = myMap [" hello "];'ならば、再割り当てを引き起こすのに必要な数の要素を挿入しても 'val'は文字列' hello ' '。イテレータから参照を取得する場合も同様です。イテレータは後で無効にすることができますが、値の参照は有効なままです。 – jogojapan

+0

http://stackoverflow.com/questions/6438086/iterator-invalidation-rulesベクターの挿入を確認してください。ベクトル:新しいコンテナのサイズが以前の容量より大きい場合を除いて、挿入ポイントの前のすべてのイテレータと参照は影響を受けません(この場合、すべてのイテレータと参照は無効になります)[23.2.4.3/1] – q0987

関連する問題