如何让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();
}
但它无法编译。
我需要做什么才能让 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);
}
};
并将其作为模板参数传递给地图的构造:
boost::unordered_map<boost::flyweight<std::string>, boost::flyweight<std::string> , flyweight_hash > map;
在这种情况下,我不明白重载 hash_value 不起作用的方式。
I am trying to do the following:
boost::unordered_map<boost::flyweight<std::string>, boost::flyweight<std::string> > map;
boost::flyweight<std::string> foo(name);
map[foo] = foo;
But the compiler complains:
"error C2665: 'boost::hash_value' : none of the 17 overloads could convert all the argument types".
But I have defined the following function:
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();
}
But it doesn´t compile.
What do I need to do to make boost unordered_map to support flyweight?
[EDIT]
I got it to work with the following code:
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);
}
};
and passed it as a template parameter to the construction of the map:
boost::unordered_map<boost::flyweight<std::string>, boost::flyweight<std::string> , flyweight_hash > map;
In this case I don´t understand way overloading hash_value didn´t worked.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
boost::hash
通过参数相关查找 (ADL) 调用hash_value
。您正在尝试为命名空间boost
中的类定义hash_value
函数。因此,您的hash_value
函数也需要进入此命名空间才能使 ADL 正常工作。不幸的是,向外部名称空间添加函数是相当邪恶的,应该避免。您使用自定义哈希器的解决方案似乎不错。一个小示例代码来说明:
boost::hash
callshash_value
through argument dependent lookup (ADL). You are trying to define ahash_value
function for a class in namespaceboost
. Hence yourhash_value
function would need to go into this namespace as well for ADL to work. Unfortunately, adding functions to a foreign namespace is rather evil and should be avoided. Your solution of using a custom hasher seems fine.A little example code to illustrate:
对已经被散列过的东西进行散列是很遗憾的。 Flyweight 保留相等对象的单个实例,因此散列该实例的地址而不是其内容更有效。我执行如下操作(在
std
中,而不是在boost
中,因为我使用的是 C++11,所以我扩展了std::hash
code>,而不是boost::hash
):我已确认这是设计使然,而不是偶然:http://lists.boost.org/boost-users/2013/03/78007 .php
It is a pity to hash something which has already been hashed. Flyweight keeps a single instance of equal objects, so it is more efficient to hash the address of this instance, instead of its content. I do as follows (in
std
, not inboost
, as I'm using C++11, so I'm extendingstd::hash
, notboost::hash
):I have been confirmed that this works by design, not by accident: http://lists.boost.org/boost-users/2013/03/78007.php