Issue 3705: Hashability shouldn't depend on basic_string's allocator (original) (raw)
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 hashpmr::string; template<> struct hashpmr::u8string; template<> struct hashpmr::u16string; template<> struct hashpmr::u32string; template<> struct hashpmr::wstring;
-1- If
Sis one of these string types,SVis the corresponding string view type, andsis an object of typeS, thenhash<S>()(s) == hash<SV>()(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<basic_string<char, char_traits, allocator>; template<> struct hash<basic_string<char8_t, char_traits, allocator>;
template<> struct hash<basic_string<char16_t, char_traits, allocator>;
template<> struct hash<basic_string<char32_t, char_traits, allocator>;
template<> struct hash<basic_string<wchar_t, char_traits, allocator>;
template<> struct hash<basic_string<char, char_traits, pmr::polymorphic_allocator>; template<> struct hash<basic_string<char8_t, char_traits, pmr::polymorphic_allocator>;
template<> struct hash<basic_string<char16_t, char_traits, pmr::polymorphic_allocator>;
template<> struct hash<basic_string<char32_t, char_traits, pmr::polymorphic_allocator>;
template<> struct hash<basic_string<wchar_t, char_traits, 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.
- Modify 27.4.2 [string.syn], header
<string>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 hashpmr::string;template<> struct hashpmr::u8string;template<> struct hashpmr::u16string;template<> struct hashpmr::u32string;template<> struct hashpmr::wstring;
template struct hash<basic_string<char, char_traits, A>>;
template struct hash<basic_string<char8_t, char_traits, A>>;
template struct hash<basic_string<char16_t, char_traits, A>>;
template struct hash<basic_string<char32_t, char_traits, A>>;
template struct hash<basic_string<wchar_t, char_traits, A>>;[…]
- 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 hashpmr::string;template<> struct hashpmr::u8string;template<> struct hashpmr::u16string;template<> struct hashpmr::u32string;template<> struct hashpmr::wstring;
template struct hash<basic_string<char, char_traits, A>>;
template struct hash<basic_string<char8_t, char_traits, A>>;
template struct hash<basic_string<char16_t, char_traits, A>>;
template struct hash<basic_string<char32_t, char_traits, A>>;
template struct hash<basic_string<wchar_t, char_traits, A>>;-1- If
Sis one of these string types,SVis the corresponding string view type, andsis an object of typeS, thenhash<S>()(s) == hash<SV>()(SV(s))