将 unordered_set 放在 unordered_map 中
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"})));
但其中 none 编译,我得到这些错误(分别):
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)’
映射的元素(map
和 unordered_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"});
为了在 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"})));
你应该可以开始了。
大括号初始化器是完美转发不太完美的边缘情况之一。
问题是传递给函数模板参数的大括号初始化器处于非推导上下文中,不允许编译器为它们推导类型。
幸运的是,修复非常简单:只需明确使用 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*>
。
您可以使用以下代码:
for (int i=0; i<100; i++)
my_map.emplace(i, std::unordered_set<std::string>({"foo","bar"}));
它将无序集合移动到无序映射中。
如何将(静态定义的)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"})));
但其中 none 编译,我得到这些错误(分别):
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)’
映射的元素(map
和 unordered_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"});
为了在 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"})));
你应该可以开始了。
大括号初始化器是完美转发不太完美的边缘情况之一。
问题是传递给函数模板参数的大括号初始化器处于非推导上下文中,不允许编译器为它们推导类型。
幸运的是,修复非常简单:只需明确使用 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*>
。
您可以使用以下代码:
for (int i=0; i<100; i++)
my_map.emplace(i, std::unordered_set<std::string>({"foo","bar"}));
它将无序集合移动到无序映射中。