C++ - Why is boost::hash_combine the best way to combine hash-values?

后端 未结 3 2032
臣服心动
臣服心动 2020-11-30 22:41

I\'ve read in other posts that this seems to be the best way to combine hash-values. Could somebody please break this down and explain why this is the best way to do it?

3条回答
  •  北荒
    北荒 (楼主)
    2020-11-30 23:01

    ROTL For VS studio (you can deduce ROTR easily). (This is actually in reply to @WolfgangBrehm.)

    Reason: the standard trick to induce the compiler to emit ror and/or rol instructions gives an error in VS: error C4146: unary minus operator applied to unsigned type, result still unsigned.

    So... I solved the compiler error by replacing (-c) by (T(0) -c) but that is not going to be optimized.

    Adding (MS specific) specialisations solves that as inspection of the emitted optimised assembly will show.

    #include               // and some more includes, see above...
    
    template             // default template is not good for optimisation
    typename std::enable_if::value, T>::type
    constexpr rotl(const T n, const int i)
    {
        constexpr T m = (std::numeric_limits::digits - 1);
        const T c = i & m;
        //return (n << c) | (n >> (-c) & m);
        return (n << c) | (n >> (T(0) - c) & m);
    }
    template<>
    inline uint32_t rotl(const uint32_t n, const int i)
    {
        constexpr int m = (std::numeric_limits::digits - 1);
        const int c = i & m;
        return _rotl(n, c);
    }
    template<>
    inline uchar rotl(const uchar n, const int i)
    {
        constexpr uchar m = (std::numeric_limits::digits - 1);
        const uchar c = i & m;
        return _rotl8(n, c);
    }
    template<>
    inline ushort rotl(const ushort n, const int i)
    {
        constexpr uchar m = (std::numeric_limits::digits - 1);
        const uchar c = i & m;
        return _rotl16(n, c);
    }
    template<>
    inline uint64_t rotl(const uint64_t n, const int i)
    {
        constexpr int m = (std::numeric_limits::digits - 1);
        const int c = i & m;
        return _rotl64(n, c);
    }
    

提交回复
热议问题