如何使助推unordered_map支持蝇量级<string>
How to make boost unordered_map to support flyweight<string>
我正在尝试做以下事情:
boost::unordered_map<boost::flyweight<std::string>, boost::flyweight<std::string> > map;
boost::flyweight<std::string> foo(name);
map[foo] = foo;
但是编译器报错:"错误C2665: 'boost::hash_value': 17个重载都不能转换所有参数类型".
但是我已经定义了以下函数:
std::size_t hash_value(const boost::flyweight<std::string> & b)
{
boost::hash<std::string> hasher;
const std::string & str = b.get();
return hasher(str);
}
bool operator==(const boost::flyweight<std::string>& f, const boost::flyweight<std::string> & second)
{
return f.get() == second.get();
}
但是不能编译。
我需要做些什么来使boost unordered_map支持flyweight?
[编辑]我用下面的代码让它工作:
struct flyweight_hash
{
std::size_t operator()(const boost::flyweight<std::string> &elm) const
{
boost::hash<std::string> hasher;
const std::string & str = elm.get();
return hasher(str);
}
};
并将其作为模板参数传递给map的构造:
boost::unordered_map<boost::flyweight<std::string>, boost::flyweight<std::string> , flyweight_hash > map;
在这种情况下,我不明白为什么重载hash_value不工作
boost::hash
通过参数依赖查找(ADL)调用hash_value
。您正在尝试为命名空间boost
中的类定义hash_value
函数。因此,您的hash_value
函数也需要进入这个名称空间,以便ADL工作。不幸的是,将函数添加到外部命名空间是相当邪恶的,应该避免。你使用自定义散列器的解决方案似乎很好。
一个小示例代码来说明:
namespace boost {
// somewhere in boost
template<typename T>
std::size_t hash(const T& t) {
// call using ADL
// e.g. if called with object of class type foo::bar this will
// pick up foo::hash_value despite the lack of namespace
// qualification
return hash_value(t);
}
}
// your hash_value (presumably in the global namespace)
// not picked up by above call
std::size_t hash_value(boost::flyweight<T>...);
namespace boost {
// this would be picked up but is slightly evil
std::size_t hash_value(boost::flyweight<T>...);
}
对已经散列过的东西进行散列是很遗憾的。Flyweight保留相等对象的单个实例,因此对该实例的地址进行散列比对其内容进行散列更有效。我这样做(在std
,而不是在boost
,因为我使用的是c++ 11,所以我扩展了std::hash
,而不是boost::hash
):
namespace std
{
template <typename T>
struct hash<boost::flyweight<T, boost::flyweights::no_tracking>>
{
using value_type = boost::flyweight<T, boost::flyweights::no_tracking>;
size_t operator()(const value_type& ss) const
{
hash<const void*> hasher;
return hasher(&ss.get());
}
};
}
我已经确认这是设计的,不是偶然的:http://lists.boost.org/boost-users/2013/03/78007.php
相关文章:
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- EASTL矢量<向量<int>>连续的
- C - 创建矢量&lt; vector&lt; double&gt;&gt;矩阵具有分配而不是inizializ
- 为什么将此对向量&lt; map&lt; int,int&gt;&gt;中的地图进行更新.失败
- C :对矢量进行排序&lt; struct&gt;(结构有2个整数)基于结构的整数之一
- 明确的专业化“ CheckIntmap&lt;&gt;”实例化
- 什么是模板&lt;&gt;inline bla bla
- 编辑C Qlist&lt; object*&gt; gt;QML代码和一些QML警告中的模型
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误,包括&lt; ctype&gt;在原子上使用C 11
- std::vector<;uint8_t>;当C++11/14启用时,手动复制而不是调用memcpy
- 如何加入向量&lt; int&gt;到C 中的单个INT
- 是std :: set&lt; std :: future&gt;不可能存在
- 是numeric_limits&lt; int&gt; :: is_modulo从逻辑上矛盾
- opencv 2.4.7在iOS错误背景_segm.hpp #include&lt; list&gt;未找到
- 在修改列表后,std :: list&lt; t&gt; :: end()的值是否会更改
- ///<评论></评论>在Visual Studio中