警告:取消引用类型双关指针将破坏严格别名规则

问题描述

我需要为我自己的类型编写 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 (将#修改为@)