c – 没有union的hashcode的内存地址

在学习数据结构,特别是哈希表时,我们被告知,向数据类型发明有效的哈希函数是一项非常艰巨的任务,但有人建议存在快速的快捷方式.也就是说,如果我们可以假设对象不在内存中移动,并且我们可以将对象相等定义为具有相同的内存地址(使用引用相等而不是值相等),那么我们可以获得对象的哈希码,如下所示:

#include<iostream>
template<typename T>
class hashcoder {
private:
    union impl {
        T* ptr;
        int32_t hashcode; // or int64_t on a 64-bit architecture = architecture with 64-bit pointers
    };
public:
    static int32_t hash(const T& r) {
        impl i;
        i.ptr = &r;
        return i.hashcode;
    }
};

class myclass {
  // whatever
};

int main() {
    myclass m;
    std::cout << hashcoder<myclass>::hash(m) << std::endl;
}

所以我的问题是:

>使用内存地址进行哈希码是否有任何问题(再次假设引用相等是所需的行为)?
>鉴于使用联合进行转换是undefined behaviour,我们如何将内存地址转换为整数?
>(请随意指出我在上面的代码中做出的任何其他错误.C指针很容易出错.)

解决方法:

>不,没有错;散列是一个整数,并保证每个对象都是唯一的,这样可以降低碰撞的概率.
>将指针强制转换为uintptr_t.不需要工会.此外,uintptr_t具有适合平台的大小,因此您不再需要使用int32_t等.

uintptr_t hash(const T &r)
{
    return uintptr_t(&r);
}

(如果散列必须是32位,则将其转换为uint32_t,或者在64位平台上,使用appropriate magic组合两半.)

上一篇:为什么C禁止匿名结构?


下一篇:[笔记] 线性筛小记