帮助用用户定义的哈希/相等创建unordered_map
C++: Help Creating unordered_map with User-Defined Hash/Equality
我试图创建一个std::unordered_map,使用用户定义的哈希函数和相等谓词,为集成内置类型的矩阵行。我使用std::bind,因为我需要散列函数和相等函数来处理变量范围。如何使下面的代码按预期的方式编译和工作?我猜我的错误在清单的末尾,在这里我使用std::bind并实例化了std::unordered_map。
一些澄清:
我不能使用boost::hash_combine,因为我关心存储在矩阵行中的整数中的单个位,所以除非我创建自己的迭代器,否则boost::hash_combine会组合整个整数,导致错误的结果。此外,我需要哈希函数和等式函数在1到~200,000的范围内工作,因此在模板参数中指定范围不是一个合理的选择。
<>之前
template <class T,class F,class A>
struct row_hash_right : std::function<size_t(
ublas::matrix_row<ublas::matrix<T,F,A>>,
unsigned, unsigned)>
{
typedef ublas::matrix_row<ublas::matrix<T,F,A>> row_type;
// I want to use std::bind to bind the last two arguments.
size_t operator()(row_type& a, unsigned s, unsigned e)
{
// Implementation of hash function.
}
};
template <class T,class F,class A>
struct row_equal_right : std::function<bool(
ublas::matrix_row<ublas::matrix<T,F,A>>,
ublas::matrix_row<ublas::matrix<T,F,A>>,
unsigned, unsigned)>
{
typedef ublas::matrix_row<ublas::matrix<T,F,A>> row_type;
bool operator()(row_type& a, row_type& b, unsigned s, unsigned e)
{
// Implementation of equality predicate.
}
};
// Inside a function.
for (unsigned i = 0; i < len; ++i) {
for (unsigned j = i + 1; j < len; ++j) {
auto x = std::bind(r_hash, _1, i, j);
auto y = std::bind(r_equal, _1, _2, i, j);
// ERROR:
std::unordered_map<row_type, unsigned,
decltype(x), decltype(y)> m(256, x, y);
}
}
之前错误:
下面是(我认为)在尝试编译时产生的错误中最重要的部分:
/usr/include/c++/4.6/位/stl_pair.h: 92:11:错误:"std:: pair<_T1,_T2>::first '类型不完整/usr/include/boost/numeric/ublas/fwd.hpp:73:11:错误:声明const结构boost::数字:ublas: matrix_row,Boost::numeric::ublas::unbounded_array>>> '
如果你想看全部内容,我已经把它们都放在这里了:
<>之前
In file included from /usr/include/c++/4.6/bits/stl_algobase.h:65:0,
from /usr/include/c++/4.6/bits/char_traits.h:41,
from /usr/include/c++/4.6/ios:41,
from /usr/include/c++/4.6/ostream:40,
from /usr/include/c++/4.6/iostream:40,
from src/test/read_test.cpp:1:
/usr/include/c++/4.6/bits/stl_pair.h: In instantiation of ‘std::pair, boost::numeric::ublas::unbounded_array > > >, unsigned int>’:
/usr/include/c++/4.6/bits/stl_function.h:486:12: instantiated from ‘std::_Select1st, boost::numeric::ublas::unbounded_array > > >, unsigned int> >’
/usr/include/c++/4.6/bits/hashtable_policy.h:789:20: instantiated from ‘std::__detail::_Hash_code_base, boost::numeric::ublas::unbounded_array > > >, std::pair, boost::numeric::ublas::unbounded_array > > >, unsigned int>, std::_Select1st, boost::numeric::ublas::unbounded_array > > >, unsigned int> >, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, std::_Placeholder, unsigned int, unsigned int)>, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, unsigned int, unsigned int)>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, false>’
/usr/include/c++/4.6/bits/hashtable.h:105:11: instantiated from ‘std::_Hashtable, boost::numeric::ublas::unbounded_array > > >, std::pair, boost::numeric::ublas::unbounded_array > > >, unsigned int>, std::allocator, boost::numeric::ublas::unbounded_array > > >, unsigned int> >, std::_Select1st, boost::numeric::ublas::unbounded_array > > >, unsigned int> >, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, std::_Placeholder, unsigned int, unsigned int)>, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, unsigned int, unsigned int)>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>’
/usr/include/c++/4.6/bits/unordered_map.h:44:11: instantiated from ‘std::__unordered_map, boost::numeric::ublas::unbounded_array > > >, unsigned int, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, unsigned int, unsigned int)>, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, std::_Placeholder, unsigned int, unsigned int)>, std::allocator, boost::numeric::ublas::unbounded_array > > >, unsigned int> >, false>’
/usr/include/c++/4.6/bits/unordered_map.h:256:11: instantiated from ‘std::unordered_map, boost::numeric::ublas::unbounded_array > > >, unsigned int, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, unsigned int, unsigned int)>, std::_Bind, boost::numeric::ublas::unbounded_array > >(std::_Placeholder, std::_Placeholder, unsigned int, unsigned int)>, std::allocator, boost::numeric::ublas::unbounded_array > > >, unsigned int> > >’
./sal/alg/ehh.hpp:144:31: instantiated from ‘sal::ehh_results sal::compute_ehh(boost::numeric::ublas::matrix&, unsigned int) [with FloatType = double, T = unsigned int, F = boost::numeric::ublas::basic_row_major, A = boost::numeric::ublas::unbounded_array >]’
src/test/read_test.cpp:11:51: instantiated from here
/usr/include/c++/4.6/bits/stl_pair.h:92:11: error: ‘std::pair::first’ has incomplete type
/usr/include/boost/numeric/ublas/fwd.hpp:73:11: error: declaration of ‘const struct boost::numeric::ublas::matrix_row, boost::numeric::ublas::unbounded_array > > >’
如果你想散列一系列的东西,你需要像hash_combine()
这样的东西。我通常从Boost中提取这个函数(令人惊讶的是,它没有包含在标准中!)以下是我如何在std::array
s上使用它,我相信您可以将其操作成在矩阵行上工作的东西:
#include <array>
template <class T>
inline void hash_combine(std::size_t & seed, const T & v)
{
std::hash<T> hasher;
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
namespace std
{
template<typename T, size_t N> struct hash<array<T, N>>
{
inline size_t operator()(const array<T, N> & a) const
{
size_t seed = 0;
for (size_t i = 0; i != N; ++i)
{
::hash_combine(seed, a[i]);
}
return seed;
}
};
}
(以上专门化允许您使用std::unordered_set<std::array<int, 10>>
等)
如果矩阵行没有相等谓词,您还可以为矩阵行添加std::equal_to
专门化。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 使用std::multimap迭代器创建std::list
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 使用CMake创建QML插件
- 如何在c++中为模板函数实例创建快捷方式
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 试图在visual studio上用C++创建一个桌面应用程序
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 如何在C++20中创建模板别名的推导指南
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 如何创建一个空的全局类并在启动时实例化它
- 无法创建抽象类的实例
- 链接到自行创建的dll失败
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++类内存结构中创建"spacer"?
- 终端不会为C++文件创建.exe文件吗
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息