#include <iostream>
int main() {
std::hash<int> hash_f;
std::cout << hash_f(0) << std::endl;
std::cout << hash_f(1) << std::endl;
std::cout << hash_f(2) << std::endl;
std::cout << hash_f(3) << std::endl;
}
I compile with "g++ main.cpp -std=c++11" and then the result is :
0
1
2
3
Why is this happening? I don't use any library and I don't have a specialized hashing function.
Addendum : I wanted to define the hash for an unordered_set of unordered_set of int with the hash of a set being the sum of its components hashs, but if it's just identity it's not cool because the hash of {2,4} is the same than the hash of {1,5}. The simplest way to avoid that is may be to use the std::hash double function.
The other answers cover the rationale behind the identity function very well. To address your addendum:
I wanted to define the hash of an unordered_set as the sum of its components hashs, but if it's just identity it's not cool because the hash of {2,4} is the same than the hash of {1,5}. The simplest way to avoid that is may be to use the std::hash function.
As you can see, using the +
operator to combine hashes is not the best idea. To be more robust, you could use the XOR (^
) operator, or take inspiration from the approach taken, e.g., by boost::hash_combine
(details in this SO post):
seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
As an example, for your two integer pairs (1,5 / 2,4), and a seed
of 0, this would work out to
uint32_t seed = 0;
seed ^= 1 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= 5 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
// 3449077526
uint32_t seed = 0;
seed ^= 2 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
seed ^= 4 + 0x9e3779b9 + (seed << 6) + (seed >> 2);
// 3449077584