【问题标题】:boost::hash for tuple containing boost unitsboost::hash 用于包含 boost 单元的元组
【发布时间】:2020-10-16 07:40:15
【问题描述】:

我想使用带有std::tuple<A...> 键的tbb::concurrent_hash_map,其中A... 将包括升压单元类型。我目前使用的 HashCompare 结构如下所示:

template<typename K>
struct HashCompare {
    static size_t hash( const K& key )
    {
        boost::hash<K> hasher;
        return hasher(key);
    }
    static bool equal( const K& key1, const K& key2 ) {return key1 == key2;}
};

对于所有非升压单元类型,我都试过了,但对于升压单元则不然。我知道可以使用自定义类型扩展 boost::hash 函数,但我似乎无法做到这一点。由于我有很多单位,我想使用以下形式的模板来做到这一点:

std::size_t hash_value(T const& t){
    boost::hash<double> hasher;
    return hasher(t.value());
}

将此函数放在boost 命名空间或定义单位的命名空间中不起作用。

如何将 boost 散列函数扩展为自定义类型或为 HashCompare::hash 函数编写模板,该函数只接受 boost 单元?

【问题讨论】:

    标签: c++ templates boost boost-units boost-functional


    【解决方案1】:

    确实 Boost Units 不支持散列。你可以添加它:

    template <typename... T>
    size_t hash_value(boost::units::quantity<T...> const& q) {
        using boost::hash_value; // enable ADL
        return hash_value(q.value());
    }
    

    最小的演示:

    Live On Coliru

    #include <boost/functional/hash.hpp>
    #include <boost/units/unit.hpp>
    #include <boost/units/systems/si.hpp>
    
    #include <boost/units/io.hpp>
    #include <iostream>
    
    using boost::hash_value;
    
    template <typename... T>
    size_t hash_value(boost::units::quantity<T...> const& q) {
        using boost::hash_value; // enable ADL
        return hash_value(q.value());
    }
    
    int main() {
        using namespace boost::units::si;
        auto l  = 23.0*meter;
        auto dt = 2.0*second;
    
        std::cout << (l) << "\n";
        std::cout << (dt) << "\n";
        std::cout << (l/dt) << "\n";
    
        std::cout << std::hex << std::showbase;
        std::cout << hash_value(l) << "\n";
        std::cout << hash_value(dt) << "\n";
        std::cout << hash_value(l/dt) << "\n";
    }
    

    打印

    23 m
    2 s
    11.5 m s^-1
    0x4037000000000000
    0x4000000000000000
    0x4027000000000000
    

    在通用代码中使用boost::hash

    确保在实例化点可以访问重载。启用参数相关查找 (ADL):

    Live On Coliru

    #include <boost/units/unit.hpp>
    #include <boost/units/systems/si.hpp>
    
    #include <boost/units/io.hpp>
    #include <iostream>
    #include <boost/functional/hash.hpp>
    
    namespace boost::units {
        template <typename... T>
        size_t hash_value(quantity<T...> const& q) {
            using boost::hash_value; // enable ADL
            return hash_value(q.value());
        }
    }
    
    namespace detail {
        template<typename K>
            struct HashCompare {
                static size_t hash( const K& key )
                {
                    boost::hash<K> hasher;
                    return hasher(key);
                }
                static bool equal( const K& key1, const K& key2 ) {return key1 == key2;}
            };
    
        template <typename T>
        size_t test_mycompare(T const& v) {
            return HashCompare<T>::hash(v);
        }
    }
    
    int main() {
        using namespace boost::units::si;
        using boost::hash_value;
    
        auto l  = 23.0*meter;
        auto dt = 2.0*second;
    
        std::cout << (l) << "\n";
        std::cout << (dt) << "\n";
        std::cout << (l/dt) << "\n";
    
        std::cout << std::hex << std::showbase;
        std::cout << hash_value(l) << "\n";
        std::cout << hash_value(dt) << "\n";
        std::cout << hash_value(l/dt) << "\n";
    
        std::cout << detail::test_mycompare(l) << "\n";
        std::cout << detail::test_mycompare(dt) << "\n";
        std::cout << detail::test_mycompare(l/dt) << "\n";
    }
    

    打印

    23 m
    2 s
    11.5 m s^-1
    0x4037000000000000
    0x4000000000000000
    0x4027000000000000
    0x4037000000000000
    0x4000000000000000
    0x4027000000000000
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-07
      • 2017-12-27
      • 1970-01-01
      • 2022-01-07
      • 2011-01-06
      • 1970-01-01
      • 2012-06-30
      • 1970-01-01
      相关资源
      最近更新 更多