繁体   English   中英

libc ++是否为太多basic_string_view提供了哈希专用化?

[英]Is libc++ providing hash specialization for too many basic_string_view's?

每个[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>; // ... 

仅对四个“ common” basic_string_view启用hash特殊化。 其他basic_string_view禁用了其hash

[unord.hash] / 2

[...]对于库或用户均未提供类模板hash的显式或部分专业化的任何类型的Key ,将禁用hash<Key>

[unord.hash] / 4

如果H是禁用的hash专业化,则这些值为false: 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尝试都将格式错误。 尾注 ]

因此,以下最小可重现示例不应编译,因为它试图默认构造禁用的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 ++实际上为所有basic_string_view启用了hash

因此,我得出结论,这是libc ++中的错误。 我的分析正确吗?

您似乎是正确的。 的libc ++正确地禁用你的哈希std::basic_string ,但不是std::basic_string_view

更高版本:修复LLVM 9.0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM