【问题标题】:Why C++20 knows how to hash string_view, but does not know how to hash span<char>?为什么 C++20 知道如何散列 string_view,但不知道如何散列 span<char>?
【发布时间】:2021-09-29 01:21:53
【问题描述】:

我的最佳猜测是委员会要么忘记了这个用例,要么不想使用概念/要求将 span 类型限制为可以安全散列的东西(POD,无填充),或者他们不想要一半的解决方案(等待反思)...

如果有人对此感兴趣,godbolt 链接带有无用的错误消息和代码,但我认为我的问题很清楚,没有任何代码。

#include <span>
#include <unordered_set>
#include <string_view>
int main() {
    std::hash<std::string_view> h1;
    std::hash<std::span<char>> h2; // error here
}

注意:我知道 C++ std:: 库在涉及散列的情况下缺乏,例如它不能散列std::pair&lt;int,int&gt;,但我的问题特别是关于std::span

【问题讨论】:

  • std::string_view 是一个字符串的视图,并且同意为字符串提供散列函数。 std::span&lt;char&gt; 就像 std::vector&lt;char&gt;。它可能有一个字符串,或者它可能是某些东西的二进制有效负载。在这里使用的散列不太直接。
  • @NathanOliver AFAIK 有一个包含任何内容的 string_view 并没有违法,或者你指的是别的东西(比如什么哈希对常见的文本模式有很好的属性)? godbolt.org/z/5drn7se4q
  • 当然,没有实际的规则,但为什么要使用string_view 而不是查看字符串?使用它的类型来传达意图非常适合自我记录。回答是的,我的区别是那里有适合文本的散列,并且由于string_view 应该 中有文本,因此有一个散列是有意义的。 span&lt;char&gt; OTOH 可以表示任何东西,并且可能需要也可能不需要不同类型的散列。对我来说,这足以模棱两可,不能提供哈希器,就像我们没有用于 vector&lt;char&gt;array&lt;char, N&gt; 的哈希器一样

标签: c++ c++20 string-view std-span


【解决方案1】:

string_view 绝对是一个字符串; span&lt;char&gt; 只是 chars 的数组。它可能string_view 具有相同的概念含义,但你不能说这对于该类型而言是固有的。因此,标准假设每个span&lt;char&gt; 都应该被视为一个字符串是不合理的。

大多数容器没有标准定义的散列(字符串容器是唯一的例外)。原因是Ts 序列没有一个好的默认哈希算法。即使有,span&lt;char&gt; 使用该算法几乎肯定不会产生与string_view 相同的散列值。

此外,这两种类型对等价的处理方式不同。 string_view 有一个 operator== 过载; span&lt;T&gt; 没有。散列在概念上基于相等:如果两个对象比较相等,则这些对象产生的散列必须相等。但由于 span 根本没有相等性测试,散列 span 没有什么意义。

【讨论】:

  • 这种只是将问题扩展到为什么 span 没有operator==。据我所知,没有理由缺席。其他语言中的可比类型(例如,Rust 或 Swift 的 slice 等)都有 eq 和 hashing,在某些情况下还有 ordering 等等。
  • @GManNickG 我可以向你指出删除它的论文,但老实说,这是一个非常糟糕的决定,是为了回应一篇非常糟糕的论文,我们都因此而变得更糟。
  • @Barry 听起来很适合委员会。我遇到了stackoverflow.com/questions/60633668/…,它对此进行了更多讨论并链接到各种论文。
  • @Barry 这有关系吗? abseil.io/blog/20180531-regular-types
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-13
  • 2017-04-05
  • 2019-03-09
  • 2016-11-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多