[英]A std::unordered_map facade for a std::unordered_set - how?
[英]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的元素( 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"});
您可以使用以下代码:
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.