无法编译unodered_sets的比较

时间:2019-11-25 16:56:35

标签: c++11 templates unordered-set

我有几个无序集合,定义为:

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;

将函子定义为:

  1. 哈希:
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());
    }
};
  1. 平等:
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))
                                        ~~~~~~~^~~~~~~~~
  • CLang:
/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已经为我完成了比较,所以我宁愿避免编写多余的代码。

有什么主意我做错了吗?他们将不胜感激。

0 个答案:

没有答案