1

我想使用一个包含增强单元类型tbb::concurrent_hash_map的键。我现在使用的 HashCompare 结构如下所示:std::tuple<A...>A...

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 单元的函数编写模板?

4

1 回答 1

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());
}

最小的演示:

住在科利鲁

#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在通用代码中使用 with

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

住在科利鲁

#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
于 2020-06-25T23:48:48.887 回答