我想为我的名为AnimationSet的自定义类型重载std :: hash模板:
struct AnimationSet {
const AnimationData *animationData;
SceneNode *sceneNode;
bool operator==(const AnimationSet &other) const {
return ( this->animationData == other.animationData &&
this->sceneNode == other.sceneNode );
}
};
如您所见,它是一个只包含两个指针的结构。
将这些指针强制转换为unsigned int以计算AnimationSet的哈希是否合法?
namespace std {
template<>
struct hash<AnimationSet> {
size_t operator()(const AnimationSet &set) const {
hash<unsigned int> h;
return h((unsigned int)set.animationData) ^ h((unsigned int)set.sceneNode);
}
};
}
编辑: 我在哈希重载的上下文中问这个问题,但是我想知道更普遍的问题的答案:“将任何指针转换为unsigned int是否公平?”
答案 0 :(得分:8)
通常,不,指针的大小不一定与unsigned int
相同。特别是,在大多数64位系统上,它们将是两倍大,所以你要做的只是取指针的最低32位,这更有可能导致冲突(特别是因为许多指针不会有设置的最低两位,因此您只能获得有助于哈希值的30位有用信息。)
您应该#include <cstdint>
并转而投放到std::uintptr_t
。这是一个无符号整数类型,保证能够存储指针的值而不会丢失任何位。
答案 1 :(得分:3)
虽然指针实际上只是一个无符号整数值(至少在类似现代PC的系统上),但不确定是否可以使用unsigned int
。请记住,int
的大小和指针的大小可能不同(例如,在64位系统上)。
如果你想要一个大到足以适合指针的整数类型,请使用<cstdint>
中的uintptr_t
。