Home > Back-end >  How to initialize recurring `std::unordered_map` via curly braces
How to initialize recurring `std::unordered_map` via curly braces

Time:08-06

I need to initialize a type implementing tree-like structure.

Tree t1 = 1;
Tree t2 = {{"a",t1},{"b",{{"x",2},{"y",4}}},{"c",5}};

So i defined structure which inherits from std::unordered_map. I had to wrap recurring Tree in smart pointer.

//tree.h
    using std;
    struct Tree : unordered_map<string, unique_ptr<Tree>>{
        int simple;
    
        Tree() = default;
        Tree(unsigned s): simple{s}{};
        Tree(const initializer_list<pair<string, unique_ptr<Tree>>> & il): simple{s} {
            // does not compile, would not work anyway 'coz the pointer
        }
    };

I can't figure out how to specify the initializer list.

there is something that might help:

struct TreeV : vector<pair<string, TreeV>>{
...
TreeV(const vector<pair<string, TreeV>> & v) : vector<pair<string, TreeV>>(v){};
}
vector<pair<string, TreeV>> t3 = {{"a",t1},{"b",{{"x",2},{"y",4}}},{"c",5}};

How can I catch recurrent curly braces structure in the 'initializer_list'? or How can I initialize recurring pattern of std::unordered_map from curly braces structure?

CodePudding user response:

Remove the reference from the initializer list. You cannot pass rvalues while using non const references. Also remove the simple{s} from the member initializer list if s isn't even defined anywhere.

Tree(std::initializer_list<std::pair<std::string, std::unique_ptr<Tree>>> il) {};

Then something like this would compile.

Tree t = { 
  { "one", std::make_unique<Tree>() },
  { "two", std::unique_ptr<Tree>(new Tree({ // unique_ptr is used here because make_unique does not support initializer lists.
    {
      "three", std::make_unique<Tree>()
    }}))
  }
};

But I would question the use of unique_ptr altogether, is there a particular reason for using them here? I assume the memory would be managed by the unordered_map anyways? Here's how it would look without the use of unique_ptr:

// This would allow to use syntax that resembles your goal
Tree(std::initializer_list<std::pair<std::string, Tree>> il) {};
...
Tree t = { 
  { "one", {} },
  { "two", {
      { "three", {} }
    }
  }
};
  • Related