3

我想在哈希集中存储一组(智能)指针<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() );
    }
};

我的问题是:这个哈希是个好主意吗?我认为这个哈希将有零或很少的冲突(也许引擎盖下有一些素数模数破坏了我所有的乐趣)。

目的的更多细节:哈希的目的是回收大对象的存储,所以我需要一种快速的方法来检测一个大对象是否已经在垃圾箱中。

如果不是,那么对于智能或哑指针来说,理想的哈希是什么?

4

3 回答 3

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();
}
于 2011-10-18T22:28:31.373 回答
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);
}
于 2011-10-18T22:26:11.237 回答
0

整数类型的默认Boost.Hash hash函数是恒等函数,所以我不认为对指针做同样的事情是一个坏主意。它将具有相同的碰撞率。

于 2011-10-18T22:26:30.420 回答