我正在努力做以下事情:
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(); }
但它没有编译.
我需要做些什么来提升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); } };
并将其作为模板参数传递给构建地图:
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>...); }