Search code examples
c++initializationinitializer-listlist-initialization

Custom aggregate initializer list constructor


For example, nlohmann json has a way of converting an aggregate initializer list to a JSON object:

json j = {
  {"pi", 3.141},
  {"happy", true},
  {"name", "Niels"},
  {"nothing", nullptr},
  {"answer", {
    {"everything", 42}
  }},
  {"list", {1, 0, 2}},
  {"object", {
    {"currency", "USD"},
    {"value", 42.99}
  }}
};

and c++ std::map also has a aggeragte initalizer list

{
{"one": 1},
{"two": 2}
}

I'm curious about how you can write a custom (aggregate) initalizer list initalizer


Solution

  • It is easy to learn howtos in the standard library.

    Look at the std::map constructor:

    map( std::initializer_list<value_type> init,
         const Compare& comp = Compare(),
         const Allocator& alloc = Allocator() );
    

    value_type is

    std::pair<const Key, T>, Key is std::string, T is int
    

    So the constructor is

    map( std::initializer_list<std::pair<std::string, int>> init,
         const Compare& comp = Compare(),
         const Allocator& alloc = Allocator() );
    

    and can be used like with

    {
      std::pair("one", 1),
      std::pair("two", 2),
    }
    

    Then look at std::pair constructor

    pair( const T1& x, const T2& y );
    

    It can be constructed like

    std::pair<std::string, int> a{"one", 1};
    

    or

    std::pair<std::string, int> a = {"one", 1};
    

    Taking into consideration all above, a map can be constructed like with

    {
    {"one", 1},
    {"two", 2}
    }