我有几个无序集合,定义为:
std::unordered_set<std::reference_wrapper<const T>, MyHash<T>, MyEqual<T>> const &map1;
std::unordered_set<std::reference_wrapper<const T>, MyHash<T>, MyEqual<T>> const &map2;
将函子定义为:
template<typename T>
struct MyHash
{
inline size_t operator()(
std::reference_wrapper<const T> const &obj) const noexcept
{
return reinterpret_cast<size_t>(&obj.get());
}
};
template<typename T>
struct MyEqual
{
inline bool operator()(
std::reference_wrapper<const T> const &lhs,
std::reference_wrapper<const T> const &rhs) const
{
return (reinterpret_cast<size_t>(&lhs.get()) == reinterpret_cast<size_t>(&rhs.get()));
}
};
基本上将引用对象的内存地址用作哈希,并检查两个引用是否为其基础对象共享相同的内存地址是否相等。
这很好用,除,当我尝试比较两组是否相同时:
if(map1 == map2)
它不会编译,而是返回:
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/hashtable_policy.h: In instantiation of ‘bool std::__detail::_Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::_M_equal(const __hashtable&) const [with _Key = std::reference_wrapper<const std::basic_string<char> >; _Value = std::reference_wrapper<const std::basic_string<char> >; _Alloc = std::allocator<std::reference_wrapper<const std::basic_string<char> > >; _ExtractKey = std::__detail::_Identity; _Equal = MyEqual<std::basic_string<char> >; _H1 = MyHash<std::basic_string<char> >; _H2 = std::__detail::_Mod_range_hashing; _Hash = std::__detail::_Default_ranged_hash; _RehashPolicy = std::__detail::_Prime_rehash_policy; _Traits = std::__detail::_Hashtable_traits<false, true, true>; std::__detail::_Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal, _H1, _H2, _Hash, _RehashPolicy, _Traits, true>::__hashtable = std::_Hashtable<std::reference_wrapper<const std::basic_string<char> >, std::reference_wrapper<const std::basic_string<char> >, std::allocator<std::reference_wrapper<const std::basic_string<char> > >, std::__detail::_Identity, MyEqual<std::basic_string<char> >, MyHash<std::basic_string<char> >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true> >]’:
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/unordered_set.h:1671:40: required from ‘bool std::operator==(const std::unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&, const std::unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&) [with _Value1 = std::reference_wrapper<const std::basic_string<char> >; _Hash1 = MyHash<std::basic_string<char> >; _Pred1 = MyEqual<std::basic_string<char> >; _Alloc1 = std::allocator<std::reference_wrapper<const std::basic_string<char> > >; _Value = int; _Hash = std::hash<int>; _Pred = std::equal_to<int>; _Alloc = std::allocator<int>]’
/home/my_test.cpp:526:28: required from here
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/hashtable_policy.h:1957:47: error: no match for ‘operator==’ (operand types are ‘const std::reference_wrapper<const std::basic_string<char> >’ and ‘const std::reference_wrapper<const std::basic_string<char> >’)
if (__ity == __other.end() || !bool(*__ity == *__itx))
~~~~~~~^~~~~~~~~
/opt/rh/devtoolset-8/root/usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/bits/hashtable_policy.h:1957:47: fatal error: invalid operands to binary expression ('const std::reference_wrapper<const std::basic_string<char, std::char_traits<char>, std::allocator<char> > >' and 'const std::reference_wrapper<const std::basic_string<char, std::char_traits<char>, std::allocator<char> > >')
if (__ity == __other.end() || !bool(*__ity == *__itx))
~~~~~~ ^ ~~~~~~
/opt/rh/devtoolset-8/root/usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/bits/unordered_set.h:1671:23: note: in instantiation of member function 'std::__detail::_Equality<std::reference_wrapper<const std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::reference_wrapper<const std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::reference_wrapper<const std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >, std::__detail::_Identity, MyEqual<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MyHash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, std::__detail::_Hashtable_traits<false, true, true>, true>::_M_equal' requested here
{ return __x._M_h._M_equal(__y._M_h); }
^
/home/my_test.cpp:526:25: note: in instantiation of function template specialization 'std::operator==<std::reference_wrapper<const std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MyHash<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, MyEqual<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::reference_wrapper<const std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >' requested here
if(map1 == map2)
我不知道为什么,因为在定义集合时我已经为相等性提供了一个比较器。我可以明确地进行比较,但是由于STL已经为我完成了比较,所以我宁愿避免编写多余的代码。
有什么主意我做错了吗?他们将不胜感激。