Emplace unordered_set in unordered_map

How can I add a (statically defined) unordered_set to an unordered_map without copying an unordered_set?

I tried this:

std::unordered_map<int, std::unordered_set<std::string>> my_map;
for (int i=0; i<100; i++)
  my_map.emplace(i, {"foo", "bar"});

and this:

std::unordered_map<int, std::unordered_set<std::string>> my_map;
for (int i=0; i<100; i++)
  my_map.insert(i, std::move(std::unordered_set<std::string>({"foo", "bar"})));

but none of them compiles, I get these errors (respectively):

error: no matching function for call to β€˜std::unordered_map<int, std::unordered_set<std::basic_string<char> > >::emplace(int&, <brace-enclosed initializer list>)’

and

error: no matching function for call to β€˜std::unordered_map<int, std::unordered_set<std::basic_string<char> > >::insert(int&, std::remove_reference<std::unordered_set<std::basic_string<char> > >::type)’
+4
source share
4 answers

Corrected initializers are one of the edge cases when the ideal forwarding is not so perfect.

The problem is that the corrected initializers passed to the parameters of the function template are in a non-deduced context, and compilers are not allowed to infer the type for them.

Fortunately, the fix is ​​pretty simple: just specify how to use it std::initializer_list.

my_map.emplace(i, std::initializer_list<std::string>{"foo", "bar"});

The usual way to solve this problem is to do something like:

auto list = { "foo", "bar" };
my_map.emplace(i, list);

std::string, decltype(list) std::initializer_list<const char*>.

+9

( map, unordered_map) using value type = std::pair<key_t, mapped_type>. emplace unordered_set<string>!

, :

std::unordered_map<int, std::unordered_set<std::string>> my_map;
for (int i=0; i<100; i++)
    my_map.emplace(i, std::unordered_set<std::string>{"foo", "bar"});
+2

You can use the following code:

for (int i=0; i<100; i++)
  my_map.emplace(i, std::unordered_set<std::string>({"foo","bar"}));

It will move the unordered set to the unordered map.

+2
source

To insert something in std::map<Key, Value>, you need to insertstd::pair<Key, Value>

Edit:

my_map.insert(i, std::move(std::unordered_set<std::string>({"foo", "bar"})));

at

my_map.insert( std::make_pair(i, std::unordered_set<std::string>({"foo", "bar"})));

and you should be good to go.

+1
source

All Articles