使用向量作为unordered_map的关键
Use vectors as key in unordered_map
所以我想在unordered_map中使用向量作为键。我已经遵循了这个答案,我有以下内容
#include <iostream>
#include <cstdlib>
#include <tuple>
#include <unordered_map>
#include <vector>
#include <boost/functional/hash.hpp> /* hash_combine */
template <typename T>
struct vectorHasher{
std::size_t operator()(std::vector<T> &in) const
{
using boost::hash_value;
using boost::hash_combine;
// Start with a hash value of 0
std::size_t seed = 0;
T value;
for (int i=0; i< in.size(); i++)
{
value = static_cast<T>(in[i]);
hash_combine(seed, hash_value(value));
}
return seed;
}
};
int main()
{
typedef std::unordered_map< std::vector<std::size_t>, int, vectorHasher<std::vector<std::size_t> > > map_type;
map_type mymap;
std::vector<size_t> vec (3,100);
mymap[vec] = 1;
return 0;
}
,但是我在编译代码时收到以下错误。
In file included from mytest_vectorhasher.cpp:6:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/unordered_map:404:17: error:
no matching function for call to object of type 'const
vectorHasher<std::__1::vector<unsigned long, std::__1::allocator<unsigned long> >
>'
{return static_cast<const _Hash&>(*this)(__x);}
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__hash_table:1976:21: note:
in instantiation of member function
'std::__1::__unordered_map_hasher<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >,
std::__1::__hash_value_type<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, int>, vectorHasher<std::__1::vector<unsigned
long, std::__1::allocator<unsigned long> > >, true>::operator()' requested here
size_t __hash = hash_function()(__k);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/unordered_map:1443:21: note:
in instantiation of function template specialization
'std::__1::__hash_table<std::__1::__hash_value_type<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, int>,
std::__1::__unordered_map_hasher<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >,
std::__1::__hash_value_type<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, int>, vectorHasher<std::__1::vector<unsigned
long, std::__1::allocator<unsigned long> > >, true>,
std::__1::__unordered_map_equal<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >,
std::__1::__hash_value_type<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, int>,
std::__1::equal_to<std::__1::vector<unsigned long, std::__1::allocator<unsigned
long> > >, true>,
std::__1::allocator<std::__1::__hash_value_type<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, int> >
>::__emplace_unique_key_args<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, const std::__1::piecewise_construct_t &,
std::__1::tuple<const std::__1::vector<unsigned long, std::__1::allocator<unsigned
long> > &>, std::__1::tuple<> >' requested here
return __table_.__emplace_unique_key_args(__k,
^
mytest_vectorhasher.cpp:41:10: note: in instantiation of member function
'std::__1::unordered_map<std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, int, vectorHasher<std::__1::vector<unsigned
long, std::__1::allocator<unsigned long> > >,
std::__1::equal_to<std::__1::vector<unsigned long, std::__1::allocator<unsigned
long> > >, std::__1::allocator<std::__1::pair<const std::__1::vector<unsigned long,
std::__1::allocator<unsigned long> >, int> > >::operator[]' requested here
mymap[vec] = 1;
^
mytest_vectorhasher.cpp:13:17: note: candidate function not viable: no known conversion
from 'const std::__1::vector<unsigned long, std::__1::allocator<unsigned long> >'
to 'std::vector<vector<unsigned long, allocator<unsigned long> > > &' for 1st
argument
std::size_t operator()(std::vector<T> &in) const
^
1 error generated.
我搞砸了很容易吗?我做错了什么?
此示例中有两个错误。首先,哈希器的operator()
参数应该是 const。
std::size_t operator()(const std::vector<T> &in) const
// Add const here ^^^^^
其次,您将哈希类型定义为vectorHasher<std::vector<std::size_t> >
这意味着T = std::vector<std::size_t>
,这意味着您正在尝试使用std::size_t operator()(const std::vector<std::vector<std::size_t>> &in) const
向量过多的哈希器实例化哈希器。从映射类型声明中删除std::vector
,如下所示:
typedef std::unordered_map< std::vector<std::size_t>, int, vectorHasher< std::size_t > > map_type;
// Remove std::vector from this template argument ^^^^^^^^^^^
问题是您的operator()
参数错误。 当您构建您使用的vectorHasher
时
vectorHasher<std::vector<std::size_t>>
这意味着T
是一个
std::vector<std::size_t>
这意味着您的operator()
看起来像
std::size_t operator()(std::vector<std::vector<std::size_t>> &in) const
这不是你想要的。 你可以做的是直接使用T
喜欢
std::size_t operator()(const T& in) const
或者将vectorHasher
更改为
vectorHasher<std::size_t>
代码中有 2 个错误。
1)由于您将vectorHasher
定义为
template <typename T>
struct vectorHasher{
std::size_t operator()(std::vector<T> &in) const
{
// ...
}
};
以下模板实例化vectorHasher<std::vector<std::size_t>>
扩展为:
struct vectorHasher{
std::size_t operator()(std::vector<std::vector<std::size_t>> &in) const
{
// ...
}
};
而且,果然,std::vector<std::size_t>
不能传递给这个函数。
将模板的实例化更改为 vectorHasher<std::size_t>
。
2)用于哈希的struct
operator()
需要采用const
值/引用,因此您应该将其签名更改为:
std::size_t operator()(std::vector<T> const &in) const
现场演示。
相关文章:
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- 使用一个考虑到std::map中键值的滚动或换行的键
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 允许从 std::map 的密钥窃取资源?
- 有没有办法对std::unordered_set、std::unrdered_map、std::set、std::map
- 将重物插入std::map
- 使用通用值初始化 std::map,不重复
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- C++:当所有条目都保证是唯一时,替代 std::map
- 使用模板化的键类型定义 std::map,该键类型基于作为参数接收的函数
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?
- 使用字符数组作为 Map 中的键
- C++如何创建 std::map
- C++ equivalent to Java Map getOrDefault?
- 从其他容器中移动构造"std::map"
- 如何使用 uint64_t 键类型从 std::map<int, std::string> 返回值?
- 将 std::map::emplace 与返回 shared_ptr 的函数一起使用是否正确?
- C++中 std::map 的运行时复杂度是多少?
- unordered map -在c++ std::unordered_map中预分配桶