在unordered_map中设置unordered_set

时间:2015-06-24 07:43:37

标签: c++ c++11 move unordered-map emplace

如何将(静态定义的)unordered_set添加到unordered_map,而不必复制unordered_set?

我试过了:

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

和此:

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"})));

但是没有一个编译,我分别得到了这些错误:

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

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 个答案:

答案 0 :(得分:9)

支撑初始化器是完美转发不是那么完美的边缘情况之一。

问题是传递给函数模板参数的支撑初始值设定项是在非推导的上下文中,并且不允许编译器为它们推导出类型。

幸运的是,修复非常简单:只需要​​明确使用std::initializer_list

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

解决此问题的常用方法是执行以下操作:

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

但这不适用于std::string,因为decltype(list)被推断为std::initializer_list<const char*>

答案 1 :(得分:2)

地图元素(mapunordered_map)的类型为using value type = std::pair<key_t, mapped_type>。因此,emplace不会将其参数传递给unordered_set<string>构造函数!

一旦你意识到这一点,解决方案就是easy

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 :(得分:2)

您可以使用以下代码:

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

它会将无序集移动到无序映射中。

答案 3 :(得分:1)

要在std::map<Key, Value>中插入内容,您需要插入std::pair<Key, Value>

变化:

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

成:

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

你应该好好去。

相关问题