C++ Logo

std-discussion

Advanced search

Re: C++17 std::hash disabled specializations

From: Daniel Krügler <daniel.kruegler_at_[hidden]>
Date: Wed, 15 Apr 2020 17:42:29 +0200
Am Mi., 15. Apr. 2020 um 16:13 Uhr schrieb Edward Diener via
Std-Discussion <std-discussion_at_[hidden]>:
>
> In C++17 if a std::hash specialization for a key is not provided and is
> therefore considered a disabled specialization, is it a compiler error
> if an unordered associate container is instantiated with that key ?
>
> As an example:
>
> struct MyStruct
> {
> int x;
> long y;
> MyStruct(int a, long b) : x(a), y(b) {}
> };
>
> /* No std::hash specialization is provided for MyStruct */
>
> MyStruct my1(1,2);
>
> std::unordered_set<MyStruct> oname;
> oname.insert(my1);
>
> Should the code cause a compilation error in C++17 and above ?

The standard says for a disabled specialization:

"these values are false: is_default_constructible_v<H>,
is_copy_constructible_v<H>, is_move_constructible_v<H>,
is_copy_assignable_v<H>, and is_move_assignable_v<H>. Disabled
specializations of hash are not function object types (23.14)."

For unordered associative containers, C++17 imposes the requirement

"Hash shall be a unary function
object type such that the
expression hf(k) has type
size_t."

For the default constructor the requirements

"hasher and
key_equal are
DefaultConstructible."

are imposed.

Technically these are pre-conditions whose violation would lead to UB.
But given the above mentioned characteristics of disabled hash
specializations I would expect sane implementations to make the code
ill-formed, e.g. when the constructor of the set is invoked or the
when insert is called.

I'm not sure whether this actually answers your question, though. Can
you elaborate?

Thanks,

- Daniel

Received on 2020-04-15 10:45:33