За [string.view.synop] :
// ...
// [string.view.hash], hash support
template<class T> struct hash;
template<> struct hash<string_view>;
template<> struct hash<u16string_view>;
template<> struct hash<u32string_view>;
template<> struct hash<wstring_view>;
// ...
Только для четырех "общих" basic_string_view
с разрешена специализация hash
. У остальных basic_string_view
их hash
отключены.
За [unord.hash] / 2 :
[...] Для любого типа Key
, для которого ни библиотека, ни пользователь
обеспечивает явную или частичную специализацию шаблона класса
hash
, hash<Key>
отключено.
За [unord.hash] / 4 :
Если H
является отключенной специализацией hash
, эти значения ложны:
is_default_constructible_v<H>
, is_copy_constructible_v<H>
,
is_move_constructible_v<H>
, is_copy_assignable_v<H>
и
is_move_assignable_v<H>
. Отключенные специализации hash
не функциональные типы объектов. [ Примечание: Это означает, что
Специализация хэша существует, но любые попытки использовать его как Hash
будет плохо сформирован. & Mdash; Конечная нота ]
Следовательно, следующий минимальный воспроизводимый пример не должен компилироваться, поскольку он пытается по умолчанию создать отключенную специализацию hash
:
#include <string_view>
// trait is a char trait distinct from std::char_traits<char>
struct trait :std::char_traits<char> {
using char_traits<char>::char_traits;
};
int main()
{
[[maybe_unused]] std::hash<std::basic_string_view<char, trait>> x;
}
Однако, это компилирует отлично на Clang 8.0.0. Копаясь в источнике libc ++, мы видим :
// [string.view.hash]
template<class _CharT, class _Traits>
struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, _Traits> >
: public unary_function<basic_string_view<_CharT, _Traits>, size_t>
{
_LIBCPP_INLINE_VISIBILITY
size_t operator()(const basic_string_view<_CharT, _Traits> __val) const _NOEXCEPT {
return __do_string_hash(__val.data(), __val.data() + __val.size());
}
};
Таким образом, libc ++ фактически включает hash
для всех basic_string_view
с.
Поэтому я делаю вывод, что это ошибка в libc ++. Является ли мой анализ правильным?