c++hashclang++unordered-set

Why this code gives me compiler error: "Static assertion failed due to...the hash does not meet the Hash requirement"


Code pasted below:

auto myComp = []( std::array<const string, 3> &a, std::array<const string, 3> &b )
{
    if ( a[0] == b[0] && a[1] == b[1] && a[2] == b[2] ) {
        return true;
    } else {
        return false;
    }
};
auto myHash = []( std::array<const string, 3> &a )
{
    return std::hash<std::string>()( a[0] )
    ^ std::hash<std::string>()( a[1] )
    ^ std::hash<std::string>()( a[2] );
};
std::unordered_set<std::array<const string, 3>, decltype( myHash ), decltype( myComp )> unordSet( 16, myHash, myComp );

The whole error message is:

MacOSX15.1.sdk/usr/include/c++/v1/__hash_table:607:17 Static assertion failed due to requirement 'integral_constant<bool, false>::value': the specified hash does not meet the Hash requirements

Many thanks in advance.

EDIT:

I managed to find out the definition of the check:

#ifndef _LIBCPP_CXX03_LANG
template <class _Key, class _Hash>
using __check_hash_requirements _LIBCPP_NODEBUG =
    integral_constant<bool,
                      is_copy_constructible<_Hash>::value && is_move_constructible<_Hash>::value &&
                          __invokable_r<size_t, _Hash, _Key const&>::value >;

Turns out it is this condition that fails the test:

__invokable_r<size_t, _Hash, _Key const&>::value

Solution

  • Yes, you are right, the problem here is that unordered map accepts hashing function only with const reference key, it is necessary in order to guarantee data immutability during different actions to make the container work correctly, it is also accepted in STL library. That is

    auto myComp = [](const array<const string, 3> &a, const.   array<const string, 3> &b)
    {
        return (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);
    };
    
    auto myHash = [](const array<const string, 3> &a)
    {
        return hash<string>()(a[0]) ^ hash<string>()(a[1]) ^ hash<string>()(a[2]);
    };
    

    I also suggest you read the book "Effective C++" by Scott Meyers (Chapter 3), which discusses the topic of effective use of const reference