问题描述
我需要为我自己的类型编写 std::hash 实现,而且这个实现必须很快。请考虑代码示例:
#include <unordered_set>
#include <cstdint>
struct Vector
{
float x,y,z;
};
inline bool operator ==( const Vector & a,const Vector & b )
{
return a.x == b.x && a.y == b.y && a.z == b.z;
}
namespace std
{
template<>
struct hash<Vector>
{
size_t operator()( Vector const& p ) const noexcept
{
return
( (size_t)*reinterpret_cast<const std::uint64_t*>(&p.x) ) ^
( (size_t)*reinterpret_cast<const std::uint32_t*>(&p.z) << 16 );
}
};
}
int main()
{
std::unordered_set<Vector> s;
s.insert( Vector{ 0,0 } );
s.insert( Vector{ 0,1 } );
return 0;
}
它在实践中运行良好(当 float 为 32 位宽时),但 gcc 会发出一些警告:
main.cpp: In member function 'std::size_t std::hash<Vector>::operator()(const Vector&) const':
main.cpp:23:24: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
23 | ( (size_t)*reinterpret_cast<const std::uint64_t*>(&p.x) ) ^
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:24:24: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
24 | ( (size_t)*reinterpret_cast<const std::uint32_t*>(&p.z) << 16 );
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
仅抑制警告是否安全?或者有更好的方法来编写类似的代码而不牺牲性能?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)