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
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