我想在哈希集中存储一组(智能)指针,<boost/unordered_set>
。经过10秒的思考,我想出了这个哈希函数:
typedef boost::shared_ptr<myType> ref_t;
struct SharedPtrHash : public std::unary_function<ref_t, std::size_t> {
std::size_t operator()(ref_t const& obj) const {
return reinterpret_cast<std::size_t>( obj.get() );
}
};
我的问题是:这个哈希是个好主意吗?我觉得这个哈希会有零或很少的碰撞(也许在引擎盖下有一些素数模数会破坏我所有的乐趣)。
有关目的的更多详细信息:散列的目的是回收大型对象的存储,因此我需要一种快速方法来检测大型对象是否已经存在于垃圾箱中。
如果不是,对于指针来说什么是理想的哈希,无论是聪明的还是愚蠢的?
答案 0 :(得分:4)
如果要检测不相同的对象,即使它们的内容可能相同,您也无选择但要在哈希中使用对象的地址。唯一的问题是是直接使用地址还是通过公式运行它。除以sizeof(mytype)
会收紧分布中的漏洞。
修改:这是一个未经测试的模板实现,应该适用于所有shared_ptr
类型,以及equal_to
函数来完成std::unordered_set
的要求。如果您有其他对象需要基于值的散列而不是指针,请不要使用此通用实现。
template<typename T>
size_t hash(const std::shared_ptr<T> & ptr)
{
return ((size_t) ptr.get()) / sizeof(T);
}
template<typename T>
bool equal_to(const std::shared_ptr<T> & left, const std::shared_ptr<T> & right)
{
return left.get() == right.get();
}
答案 1 :(得分:1)
以下代码完美编译(GCC 4.7,Boost 1.47):
#include <boost/unordered_set.hpp>
#include <boost/shared_ptr.hpp>
struct Foo { };
int main()
{
boost::unordered_set<boost::shared_ptr<int>> s;
boost::shared_ptr<int> pi(new int);
s.insert(pi);
boost::unordered_set<boost::shared_ptr<Foo>> t;
boost::shared_ptr<Foo> pf(new Foo);
t.insert(pf);
}
答案 2 :(得分:0)
整数类型的默认Boost.Hash
hash
函数是标识函数,因此我不认为对指针执行相同操作是一个坏主意。它具有相同的碰撞比率。