boost :: hash для кортежа, содержащего элементы повышения
Я хочу использовать tbb::concurrent_hash_map
с ключом std::tuple<A...>
где 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
пространство имен или в пространстве имен, где определены единицы, не работали.
Как можно расширить функцию ускоренного хеширования на типы coustum или написать шаблон для HashCompare::hash
функция, которая принимает только повышающие единицы?
1 ответ
В Indeed 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
в общем коде
Убедитесь, что перегрузка доступна в момент создания экземпляра. Включить поиск, зависимый от аргументов (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