5

My best guesses are that committee either forgot about this use case or did not want to use concepts/requires to restrict the span type to something that can be safely hashed(POD, no padding), or they did not want half solutions(waiting for reflection)...

If somebody is interested here is godbolt link with unhelpful error messages and code, but I presume my question is clear without any code.

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

note: I know C++ std:: library is lacking in cases when it comes to hashing, e.g. it can not hash std::pair<int,int>, but my question is in particular about the std::span.

NoSenseEtAl
  • 28,205
  • 28
  • 128
  • 277
  • 2
    `std::string_view` is a view to a string, and having a hashing functions for strings was agreed to. `std::span` is like a `std::vector`. It might have a string in it, or it could be binary payload for something. What hashing to use here is less straight forward. – NathanOliver Jul 21 '21 at 16:41
  • 1
    @NathanOliver AFAIK there is nothing illegal about having a string_view with any content in it, or are you refering to something else(like what hash has good properties for common text patterns)? https://godbolt.org/z/5drn7se4q – NoSenseEtAl Jul 21 '21 at 16:50
  • 3
    Sure, there is no actual rule, but why use a `string_view` for something other than a view into a string? Using it's type to convey intention is great for self documentation. Ans yes, my distiction is there are hashes out there that are good for text, and since `string_view` *should* have text in it, it makes sense to have a hasher for it. `span` OTOH can represent anything, and that may or may not need a different type of hashing. For me that is ambiguity enough not to provide a hasher, just like we don't have one for `vector` or `array` – NathanOliver Jul 21 '21 at 16:54

1 Answers1

2

string_view is very definitely a string; a span<char> is just an array of chars. It could have the same conceptual meaning as a string_view, but you cannot say that this is inherently true of the type. And therefore, it is not reasonable for the standard to assume that every span<char> ought to be treated equivalently to a string.

Most containers don't have standard-defined hashing (the string containers being the only exception). The reason being that there's not a good default hash algorithm for a sequence of Ts. And even if there was, span<char> using that algorithm almost certainly wouldn't produce the same hashed value as a string_view.

Furthermore, the two types treat equivalency differently. string_view has an operator== overload; span<T> does not. Hashing is conceptually based on equality: if two objects compare equal, then the hashes produced by those objects must be equal. But since span has no equality testing at all, hashing a span makes little sense.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 1
    This sort of just expands the question to why span doesn't have `operator==`. As far as I can tell, there is no reason for this absence. The comparable type in other languages (e.g., Rust's or Swift's slice, etc.) all have eq and hashing, and in some cases ordering and so on. – GManNickG Jul 21 '21 at 17:56
  • 2
    @GManNickG I could point you to the paper that removed it, but honestly it's a pretty bad decision made in response to a pretty bad paper and we're all worse off for it. – Barry Jul 21 '21 at 18:06
  • 1
    @Barry Sounds about right for the committee. I came across https://stackoverflow.com/questions/60633668/why-does-stdspan-lack-the-comparison-operators which discusses it more and links to various papers. – GManNickG Jul 21 '21 at 18:13
  • @Barry is this related? https://abseil.io/blog/20180531-regular-types – NoSenseEtAl Jul 21 '21 at 19:22