次のコードを検討してください。
unordered_set<T> S = ...;
for (const auto& x : S)
if (...)
S.insert(...);
これは壊れていますよね?S に何かを挿入すると、イテレータが (再ハッシュのために) 無効になる可能性があり、内部では S.begin ... S.end を使用しているため、range-for が壊れます。
これに対処するパターンはありますか?
1 つの方法は次のとおりです。
unordered_set<T> S = ...;
vector<T> S2;
for (const auto& x : S)
if (...)
S2.emplace_back(...);
for (auto& x : S2)
S.insert(move(x));
これは不格好に思えます。私が行方不明になっているより良い方法はありますか?
(具体的には、手動で作成したハッシュ テーブルを使用していて、ループの最後まで再ハッシュをブロックできる場合は、最初のバージョンを使用しても安全です。)
アップデート:
http://en.cppreference.com/w/cpp/container/unordered_map/insertから
挿入により再ハッシュが発生した場合、すべての反復子が無効になります。それ以外の場合、反復子は影響を受けません。参照は無効になりません。再ハッシュは、新しい要素数が より大きい場合にのみ発生します
max_load_factor() * bucket_count()
。
max_load_factor
再ハッシュを防ぐために何とかいじってもらえますか?