4

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

4 回答 4

9

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

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

幸运的是,修复非常简单:只需明确说明std::initializer_list.

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

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

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

但这对 s 不起作用,std::string因为decltype(list)被推断为std::initializer_list<const char*>

于 2015-06-24T07:57:13.227 回答
2

地图的元素(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"});
于 2015-06-24T07:56:51.547 回答
2

您可以使用以下代码:

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

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

于 2015-06-24T07:57:33.567 回答
1

为了在 a 中插入一些东西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"})));

你应该很高兴。

于 2015-06-24T07:57:04.097 回答