微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

我需要为我自己的类型编写 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 举报,一经查实,本站将立刻删除。