This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++23 status.

3705. Hashability shouldn't depend on basic_string's allocator

Section: 27.4.6 [basic.string.hash] Status: C++23 Submitter: Casey Carter Opened: 2022-05-26 Last modified: 2023-11-22

Priority: Not Prioritized

View all other issues in [basic.string.hash].

View all issues with C++23 status.

Discussion:

27.4.6 [basic.string.hash] says:

template<> struct hash;
template<> struct hash;
template<> struct hash;
template<> struct hash;
template<> struct hash;
template<> struct hash;
template<> struct hash;
template<> struct hash;
template<> struct hash;
template<> struct hash;

-1- If S is one of these string types, SV is the corresponding string view type, and s is an object of type S, then hash()(s) == hash()(SV(s))

Despite that the hash value of a basic_string object is equivalent to the hash value of a corresponding basic_string_view object, which has no allocator, the capability to hash a basic_string depends on its allocator. All of the enabled specializations have specific allocators, which fact becomes more clear if we expand the type aliases:

template<> struct hash, allocator>;
template<> struct hash, allocator>;

template<> struct hash, allocator>;

template<> struct hash, allocator>;

template<> struct hash, allocator>;

template<> struct hash, pmr::polymorphic_allocator>;
template<> struct hash, pmr::polymorphic_allocator>;

template<> struct hash, pmr::polymorphic_allocator>;

template<> struct hash, pmr::polymorphic_allocator>;

template<> struct hash, pmr::polymorphic_allocator>;

If the hash value doesn't depend on the allocator type, why should we care about the allocator type? I posit that we should not, and that these ten explicit specializations should be replaced by 5 partial specializations that enable hashing basic_string specializations using these combinations of character type and traits type with any allocator type.

[2022-06-21; Reflector poll]

Set status to Tentatively Ready after seven votes in favour during reflector poll.

[2022-07-15; LWG telecon: move to Ready]

[2022-07-25 Approved at July 2022 virtual plenary. Status changed: Ready → WP.]

Proposed resolution:

This wording is relative to N4910.

  1. Modify 27.4.2 [string.syn], header synopsis, as indicated:

    […]
    
    // 27.4.6 [basic.string.hash], hash support
    template struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template struct hash, A>>;
    template struct hash, A>>;
    template struct hash, A>>;
    template struct hash, A>>;
    template struct hash, A>>;
    
    […]
    
  2. Modify 27.4.6 [basic.string.hash] as indicated:

    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template<> struct hash;
    template struct hash, A>>;
    template struct hash, A>>;
    template struct hash, A>>;
    template struct hash, A>>;
    template struct hash, A>>;
    

    -1- If S is one of these string types, SV is the corresponding string view type, and s is an object of type S, then hash()(s) == hash()(SV(s))