Home > Net >  C : Nested dictionaries with unordered_maps
C : Nested dictionaries with unordered_maps

Time:10-17

I'm trying to write some code that will allow me to create a dictionary with the unordered_map object in C . It will basically look like

string1
    string2
        int_vec1
    string3
        int_vec2
...

i.e. It's a dictionary of string and integer-vector pairs, indexed by strings.

I have the following code of a simplified example to illustrate:

#include <chrono>
#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <ctime>
#include <string>
#include <unordered_map>

int main(int argc, char **argv) {
  std::string key_0 = "key_0";
  std::string key_01 = "key_01";
  std::string key_02 = "key_02";
  std::string key_1 = "key_1";
  std::string key_11 = "key_11";
  std::string key_12 = "key_12";
  std::string key_13 = "key_13";
  std::vector<int> val_01 = {1,2,3,4};
  std::vector<int> val_02 = {1,2,3,4};
  std::vector<int> val_11 = {1,2,3,4};
  std::vector<int> val_12 = {1,2,3,4};
  std::vector<int> val_13 = {1,2,3,4};

  std::unordered_map<std::string, std::unordered_map<std::string, std::vector<int>>> my_dict;
  my_dict.insert({key_0, std::pair<std::string, std::vector<int>>(key_01, val_01)});

}

However, when I compile this using gcc version 11.2.0, I get the following error

test_make_nested_unordered_map.cpp:25:17: error: no matching function for call to ‘std::unordered_map<std::__cxx11::basic_string<char>, std::unordered_map<std::__cxx11::basic_string<char>, std::vector<int> > >::insert(<brace-enclosed initializer list>)’
   25 |   my_dict.insert({key_0, std::pair<std::string, std::vector<int>>(key_01, val_01)});
      |   ~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The code seems fine to me. But I don't know why it isn't working. I would greatly appreciate some help with this. My actual code is more complicated, but this is just meant to be a simplified reproducible example.

Thanks for the help

Edit

Thanks to user 273K for the answer. I was able to get it working closer to what I expected: This code runs without issue

#include <chrono>
#include <iostream>
#include <vector>
#include <map>
#include <fstream>
#include <ctime>
#include <string>
#include <unordered_map>


void print_string_vec2(std::vector<int> vec) {
  for (auto s : vec) {
    std::cout << s << " ";
  }
  std::cout << std::endl;
}

int main(int argc, char **argv) {
  std::string key_0 = "key_0";
  std::string key_01 = "key_01";
  std::string key_02 = "key_02";
  std::string key_1 = "key_1";
  std::string key_11 = "key_11";
  std::string key_12 = "key_12";
  std::string key_13 = "key_13";
  std::vector<int> val_01 = {1,2,3,4};
  std::vector<int> val_02 = {1,2,3,4};
  std::vector<int> val_11 = {1,2,3,4};
  std::vector<int> val_12 = {1,2,3,4};
  std::vector<int> val_13 = {1,2,3,4};

  std::unordered_map<std::string, std::unordered_map<std::string, std::vector<int>>> my_dict;
  my_dict.insert({key_0, {{key_01, val_01}}});
  my_dict[key_0].insert({key_02, val_02});
  my_dict.insert({key_1, {{key_11, val_11}}});
  my_dict[key_1].insert({key_12, val_12});
  my_dict[key_1].insert({key_13, val_13});

  for (auto& u : my_dict) {
    for (auto& v : u.second) {
      std::cout << "(" << u.first << "," << v.first << "): ";
      print_string_vec2(v.second);
    }
  }

}

When run, it outputs

(key_1,key_13): 1 2 3 4
(key_1,key_12): 1 2 3 4
(key_1,key_11): 1 2 3 4
(key_0,key_02): 1 2 3 4
(key_0,key_01): 1 2 3 4

CodePudding user response:

There is no conversion from std::pair to std::unordered_map. You seem to wish

my_dict.insert({key_0, {{key_01, val_01}}});

The inner braces are initializer list for the inner unordered map with the pair initializer.

  • Related