Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9044317
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T10:57:21+00:00 2026-06-16T10:57:21+00:00

Consider the following code: unordered_set<T> S = …; for (const auto& x : S)

  • 0

Consider the following code:

unordered_set<T> S = ...;

for (const auto& x : S)
   if (...)
       S.insert(...);

This is broken correct? If we insert something into S then the iterators may be invalidated (due to a rehash), which will break the range-for because under the hood it is using S.begin … S.end.

Is there some pattern to deal with this?

One way is:

unordered_set<T> S = ...;

vector<T> S2;

for (const auto& x : S)
   if (...)
       S2.emplace_back(...);

for (auto& x : S2)
    S.insert(move(x));

This seems clunky. Is there a better way I’m missing?

(Specifically if I was using a hand-rolled hash table and I could block it from rehashing until the end of the loop, it would be safe to use the first version.)

Update:

From http://en.cppreference.com/w/cpp/container/unordered_map/insert

If rehashing occurs due to the insertion, all iterators are invalidated. Otherwise iterators are not affected. References are not invalidated. Rehashing occurs only if the new number of elements is higher than max_load_factor() * bucket_count().

Could you mess with max_load_factor somehow to prevent rehashing?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-16T10:57:22+00:00Added an answer on June 16, 2026 at 10:57 am

    Could you mess with max_load_factor somehow to prevent rehashing?

    Yes, you can set the max_load_factor() to infinity to ensure no rehashing occurs:

    #include <iostream>
    #include <limits>
    #include <unordered_set>
    
    int main()
    {
        // initialize
        std::unordered_set<int> S;
    
        for (int i = 0; i < 8; ++i)
            S.insert(i);
    
        std::cout << "buckets: " << S.bucket_count() << std::endl;
    
        // infinite max load factor => never need to rehash
        const auto oldLoadFactor = S.max_load_factor();
        S.max_load_factor(std::numeric_limits<float>::infinity());
    
        for (const auto& x : S)
        {
            if (x > 2)
                S.insert(x * 2);
        }
    
        // restore load factor, verify same bucket count
        S.max_load_factor(oldLoadFactor);
        std::cout << "buckets: " << S.bucket_count() << std::endl;
    
        // now force rehash
        S.rehash(0);
        std::cout << "buckets: " << S.bucket_count() << std::endl;
    }
    

    Note that simply setting a new load factor does no rehashing, so those are cheap operations.

    The rehash(0) bit works because it’s a request that: 1) I get at least n buckets, and 2) I have enough buckets to satisfy my max_load_factor(). We just use zero to indicate we don’t care for a minimum amount, we just want to rehash to satisfy our “new” factor, as if it was never changed to infinity.

    Of course, this isn’t exception-safe; if anything throws between the calls to max_load_factor(), our old factor is lost forever. Easily fixed with your favorite scope-guard utility or a utility class.

    Note that you get no guarantees if you’ll iterate over the new elements. You will iterate over the existing elements, but you may or may not iterate over the new elements. If that is okay (which per our chat it should be), then this will work.

    For example, consider you iterate over an unordered set of integer and for each even integer x, insert x * 2. If those always get inserted just after your currrent position (by chance of implementation-detail and container state), you will never terminate the loop except through exceptions.

    If you do need some guarantees, you need to with an alternate storage solution.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Consider the following code: struct Foo { Foo operator+(const Foo &rhs) const; // notice
Consider the following code: class A { A(const A&); public: A() {} }; int
Consider the following code: #include <iostream> struct test { void public_test() { [this]() {
Consider the following code (you can just put this in the developer console in
Consider the following code struct foo { const int txt_len; const int num_len; char
Consider the following code snippet: std::vector<int> v; v.reserve(100); v.insert(v.end(), 100, 5); v.erase(v.begin(), v.end()); std::cout
This is rather interesting, I think. Consider following code, both the window.onload and body
Consider the following code: $('.stores').click(function() { console.log($(this).data('latitude')); // -1754.26265626 console.log($(this).data('longitude')); // 65.262518 console.log(themap); //
Consider the following code. This code almost implements Chicken Scheme style recursion where most
Consider the following code: class MyClass { template <typename Datatype> friend MyClass& operator<<(MyClass& MyClassReference,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.