Same goes for std::unordered_map
vs std::map
. It means that std::map
can store objects of type std::array<T,N>
for primitive T's but std::unordered_map
cannot.
Asked
Active
Viewed 99 times
0

TonySalimi
- 8,257
- 4
- 33
- 62

abcdefasf
- 79
- 1
- 3
-
1Did you provide a hash function? – Avi Berger Aug 18 '22 at 23:30
-
I didn't for either – abcdefasf Aug 18 '22 at 23:31
-
5Simple, there is no `std::hash` specialization for `std::array`. – Deduplicator Aug 18 '22 at 23:37
-
Once you do, it should work. [See here](https://en.cppreference.com/w/cpp/utility/hash). – Avi Berger Aug 18 '22 at 23:44
-
1Good question should contain [mcve] also `doesn't work` is not description of a problem. Doesn't compile? What is error message? Crashes? What is a crash log? Give invalid results? What are they? – Marek R Aug 19 '22 at 10:14
1 Answers
0
std::array<T, N>
is not hashable by default. So, you need to implement your own hashing function for this type. A simple example hash function can be like this (adopted from here):
#include <set>
#include <array>
#include <unordered_set>
const int N = 10;
struct array_hasher
{
std::size_t operator()(std::array<int, N> const& arr) const
{
std::size_t seed = 0;
for (const auto& i : arr)
{
seed ^= std::hash<int>{}(i) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
return seed;
}
};
int main()
{
std::set<std::array<int, N>> x = {};
std::unordered_set<std::array<int, N>, array_hasher> y = {};
return 0;
}

TonySalimi
- 8,257
- 4
- 33
- 62
-
That's a good tidbit, but it's worth pointing out that `unordered_set` requires that its members have unchanging values. That is, if the array or its hash changes, all guarantees go out the window. – Tim Roberts Aug 18 '22 at 23:55
-
-
-
@TimRoberts Agreed ! In an `unordered_set<>`, each object's value is its key. So, the objects should not be changed. – TonySalimi Aug 19 '22 at 00:03
-
@abcdefasf As pointed by @Deduplicator, `std::set` is a tree-like data structure. It means that it always needs a comparison mechanism for its elements (which is already supported by `std::array` itself). On the other hand, `std::unordered_set` is a hash-table-like data structure, so it needs a hashing function for its elements. As far as this hashing function does not exist by default in standard library (for `std::array`), you need to implement it yourself ! – TonySalimi Aug 19 '22 at 00:08
-
4Specializing `std::hash` on a `std::array
` is UB. Furthermore, that's a really bad hash function. – Passer By Aug 19 '22 at 00:40 -
More specifically, specializing `std::hash` on a standard library type is Undefined Behavior. And this hash only produces odd numbers. – Drew Dormann Aug 19 '22 at 01:39
-
No reason to specialize `std::hash` for `std::array` (technical UB) Just add a lambda – doug Aug 19 '22 at 04:48