繁体   English   中英

在unordered_map中设置unordered_set

[英]emplace unordered_set in unordered_map

如何将(静态定义的)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)’

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

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

幸运的是,修复非常简单:只需要​​明确使用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*>

map的元素( mapunordered_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"});

您可以使用以下代码:

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

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

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

你应该好好去。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM