c – 如何使boost unordered_map支持flyweight

我正在努力做以下事情:
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>...);
}

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...