Search code examples
c++unordered-map

C++ Initialize unordered_map by method called by Constructor initializer list throws exception


I'm trying to populate an unordered_map [class member] in a method called in the Constructor initializer list. I get a runtime exception at map[0] = 1 which seems to be due to the member not being constructed prior to the method being called. (I put a breakpoint on the unordered_map constructor and it was not hit). Is there a way to force the construction of the unordered_map member prior to the method being called?

#include <iostream>
#include <unordered_map>

class Base
{
public:
   Base(int chan) { }
};
class Foo : public Base
{
   std::unordered_map<int, int> map;
   int Init(int chan)
   {
      // fill map
      map[0] = 1;
      map[1] = 3;
      return map[chan];
   }
public:
   Foo(int chan) : Base(Init(chan)) { }
};

int main()
{
   Foo foo(0);
}

Using Visual Studio 2019.


Solution

  • Off the top, here are two ideas I have. First:

    struct MapWrapper {
      std::unordered_map<int, int> map;
    };
    
    class Foo : private MapWrapper, public Base {
      /* The rest of the class can remain unchanged, except that
         there's no `map` member; it's inherited from MapWrapper */
    };
    

    This forces map to be constructed before Base.


    Second:

    class Foo : public Base
    {
       std::unordered_map<int, int> map;
    
       static std::unordered_map<int, int> MakeMap() {
         std::unordered_map<int, int> map;
         map[0] = 1;
         map[1] = 3;
         return map;
       }
       Foo(int chan, std::unordered_map<int, int>&& temp_map)
         : Base(temp_map[chan]), map(std::move(temp_map)) {}
    public:
       Foo(int chan) : Foo(chan, MakeMap()) {}
    };
    

    This uses delegating constructor trick to essentially simulate a local variable in the constructor initializer list.