Reputation: 17248
I am using a Boost strong typedef to strong-type uint64_t
:
BOOST_STRONG_TYPEDEF(uint64_t, MyInt)
and an std::unordered_map
using this:
std::unordered_map<MyInt, int> umap;
Unfortunately I get a lot of compiler errors (can't paste here as they're on another machine):
error: static assertion failed: hash function must be invocable with an argument of key type
.static_assert(__is_invocable<const _H1&, const _Key&>)
error: use of deleted function 'std::__detail::_Hashtable_ebo_helper
_Hashtable() = default;
(+ a lot more I cannot type)
Using a Boost strong type as the key definitely causes the problem because if I remove the unordered_map
I get no compiler errors.
Upvotes: 1
Views: 300
Reputation: 6805
From the boost documentation about BOOST_STRONG_TYPEDEF
, it is clearly mentioned that it defines a new type wrapping the target inner type (it is not a simple alias).
Knowing that, there is no defined std::hash<MyInt>
specialization available (required by std::unordered_map<MyInt, int>
) since MyInt
is now a distinct type from uint64_t
.
You just need to provide one and it should work as expected.
For instance:
namespace std
{
template <>
struct hash<MyInt>
{
size_t operator()(const MyInt & m) const
{
return hash<uint64_t>{}(m);
}
};
}
Edit:
As pointed out in comments, you could also directly pass the proper std::hash<>
specialization to use from the std::unordered_map<>
instantiation as the third template parameter since MyInt
is implicitly convertible to uint64_t
(as mentioned in the boost documentation as well).
It would then become:
std::unordered_map<MyInt, int, std::hash<uint64_t>> umap;
No need to define your own std::hash<MyInt>
specialization anymore.
Upvotes: 4