unordered_map/unordered_set의 튜플에 대한 일반 해시
Q: 왜 std::unordered_map
표준 C에서 unordered_map 또는 unordered_set과 같은 연관 컨테이너의 키로 튜플을 사용하려면 사용자 정의 해시 함수를 정의해야 합니다.
Q: 가변 템플릿을 사용하지 않고 C 0x 튜플에 대해 자동화할 수 있습니까?
예, 다음 코드를 사용합니다.
namespace std{ namespace { template <class T> inline void hash_combine(std::size_t& seed, T const& v) { seed ^= std::hash<T>()(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); } template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1> struct HashValueImpl { static void apply(size_t& seed, Tuple const& tuple) { HashValueImpl<Tuple, Index-1>::apply(seed, tuple); hash_combine(seed, std::get<Index>(tuple)); } }; template <class Tuple> struct HashValueImpl<Tuple,0> { static void apply(size_t& seed, Tuple const& tuple) { hash_combine(seed, std::get<0>(tuple)); } }; } template <typename ... TT> struct hash<std::tuple<TT...>> { size_t operator()(std::tuple<TT...> const& tt) const { size_t seed = 0; HashValueImpl<std::tuple<TT...> >::apply(seed, tt); return seed; } }; }<p><strong>Q: 더 간단한 솔루션이 있습니까? ?</strong></p> <p><strong>표준 부적합 솔루션(ADL 활성화):</strong></p> <pre class="brush:php;toolbar:false">#include <tuple> namespace std{ namespace { template <class T> inline void hash_combine(std::size_t& seed, T const& v) { seed ^= std::hash<T>()(v) + 0x9e3779b9 + (seed<<6) + (seed>>2); } template <class Tuple, size_t Index = std::tuple_size<Tuple>::value - 1> struct HashValueImpl { static void apply(size_t& seed, Tuple const& tuple) { HashValueImpl<Tuple, Index-1>::apply(seed, tuple); hash_combine(seed, std::get<Index>(tuple)); } }; template <class Tuple> struct HashValueImpl<Tuple,0> { static void apply(size_t& seed, Tuple const& tuple) { hash_combine(seed, std::get<0>(tuple)); } }; } template <typename ... TT> struct hash<std::tuple<TT...>> { size_t operator()(std::tuple<TT...> const& tt) const { size_t seed = 0; HashValueImpl<std::tuple<TT...> >::apply(seed, tt); return seed; } }; }
표준 부적합 솔루션(ADL 없음):
엄격한 표준 준수를 달성하려면 위 코드를 별도의 네임스페이스(예: hash_tuple)로 이동하고 구문을 수정하여 사용자 정의 해시 함수를 명시적으로 지정해야 합니다.
namespace hash_tuple{ // Forward non-tuple types to std::hash template <typename TT> struct hash { size_t operator()(TT const& tt) const { return std::hash<TT>()(tt); } }; }
hash_combine 및 hash_tuple 대응 항목이 있는 비준수 솔루션의 HashValueImpl. 마지막으로 다음 구문을 사용하십시오.
unordered_set<tuple<double, int>, hash_tuple::hash<tuple<double, int>>> test2;
위 내용은 사용자 정의 해시 함수를 정의하지 않고 `std::unordered_map`이 작동하도록 만드는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!