unordered_map 以对作为键 (C++) 的构建失败
Build fails for unordered_map with pair as a key (C++)
我知道可以使用 std::pair
作为 std::unordered_map
的键。在我的例子中,我需要在对中使用 std::type_index
。但是在构建它时遇到一些问题。我的代码是:
template<class Base, class Result, bool Commutative>
struct Multimethod2
{
using Args = std::pair<std::type_index, std::type_index>;
using Method = std::function<bool(Base *, Base *)>;
struct ArgsHash {
std::size_t operator () (Args &p) const {
std::size_t h1 = std::hash<std::type_index>()(p.first);
std::size_t h2 = std::hash<std::type_index>()(p.second);
return h1 ^ h2;
}
};
struct KeyEqual
{
bool operator()(const Args &a1, const Args &a2) const
{
return (a1.first == a2.first && a1.second == a2.second) ||
(a1.first == a2.second && a1.second == a2.first);
}
};
std::unordered_map<Args, Method, ArgsHash, KeyEqual> methods;
...
}
出现错误:
/usr/include/c++/7/bits/hashtable_policy.h:87: error: no match for call to ‘(const Multimethod2<Shape, bool, true>::ArgsHash) (const std::pair<std::type_index, std::type_index>&)’
noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/7/bits/hashtable_policy.h:87: error: binding reference of type ‘Multimethod2<Shape, bool, true>::Args& {aka std::pair<std::type_index, std::type_index>&}’ to ‘const std::pair<std::type_index, std::type_index>’ discards qualifiers
noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/7/type_traits:154: error: ‘value’ is not a member of ‘std::__and_<std::__is_fast_hash<Multimethod2<Shape, bool, true>::ArgsHash>, std::__detail::__is_noexcept_hash<std::pair<std::type_index, std::type_index>, Multimethod2<Shape, bool, true>::ArgsHash> >’
: public integral_constant<bool, !_Pp::value>
^~~~
...
这里的语法有什么问题?
根据哈希要求,ArgsHash::operator()
应该 Args
乘以 const&
。
顺便说一句,你的哈希函数可能不好(当你有两个相同的 type_index 时会发生什么?)
组合哈希值并非易事(没有 std::hash_combine 是有原因的);无论如何,您可能想尝试 boost.hash_combine 一个现成的 或多或少 通用解决方案...
我知道可以使用 std::pair
作为 std::unordered_map
的键。在我的例子中,我需要在对中使用 std::type_index
。但是在构建它时遇到一些问题。我的代码是:
template<class Base, class Result, bool Commutative>
struct Multimethod2
{
using Args = std::pair<std::type_index, std::type_index>;
using Method = std::function<bool(Base *, Base *)>;
struct ArgsHash {
std::size_t operator () (Args &p) const {
std::size_t h1 = std::hash<std::type_index>()(p.first);
std::size_t h2 = std::hash<std::type_index>()(p.second);
return h1 ^ h2;
}
};
struct KeyEqual
{
bool operator()(const Args &a1, const Args &a2) const
{
return (a1.first == a2.first && a1.second == a2.second) ||
(a1.first == a2.second && a1.second == a2.first);
}
};
std::unordered_map<Args, Method, ArgsHash, KeyEqual> methods;
...
}
出现错误:
/usr/include/c++/7/bits/hashtable_policy.h:87: error: no match for call to ‘(const Multimethod2<Shape, bool, true>::ArgsHash) (const std::pair<std::type_index, std::type_index>&)’
noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/7/bits/hashtable_policy.h:87: error: binding reference of type ‘Multimethod2<Shape, bool, true>::Args& {aka std::pair<std::type_index, std::type_index>&}’ to ‘const std::pair<std::type_index, std::type_index>’ discards qualifiers
noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/7/type_traits:154: error: ‘value’ is not a member of ‘std::__and_<std::__is_fast_hash<Multimethod2<Shape, bool, true>::ArgsHash>, std::__detail::__is_noexcept_hash<std::pair<std::type_index, std::type_index>, Multimethod2<Shape, bool, true>::ArgsHash> >’
: public integral_constant<bool, !_Pp::value>
^~~~
...
这里的语法有什么问题?
根据哈希要求,ArgsHash::operator()
应该 Args
乘以 const&
。
顺便说一句,你的哈希函数可能不好(当你有两个相同的 type_index 时会发生什么?)
组合哈希值并非易事(没有 std::hash_combine 是有原因的);无论如何,您可能想尝试 boost.hash_combine 一个现成的 或多或少 通用解决方案...