Reputation: 25938
Is it possible to find out the hash value (hashed key) for an element in an unordered_set
?
For example;
unordered_set<string> errorStates;
errorStates.insert("File does not exist");
// Can I get the hash of this key?
int ERR_FILE_NOT_EXISTS = errorStates.keyHash("File does not exist");
Also would the hash for File does not exist
always be the same? Would the hash be the same if I run my program and insert 20 values into errorStates
and when I run the program and insert 200? The idea is the hash will be the unique error id and write the hash to a file.
I am creating a Status
class to easily return error/success outcomes from functions and get an error message from an error code - see below for its partial implementation. But maybe there is an better more appropriate way?
//usage
Status evtState = onMouseMove();
Status copyState = fileCopy();
class Status
{
public:
static STATE registerState(const tstring &stateMsg)
{
states.emplace(stateMsg);
return states.hashValue(stateMsg);
}
Status(const STATE &state) : state(state) {}
~Status() {}
string toString()
{
unordered_set<tstring>::const_iterator ele = states.find(state);
return (ele != states.end()) ? *ele : "Undefined";
}
ostream& operator<<(Status& obj)
{
return cout << obj.toString();
}
private:
static unordered_set<tstring> states;
const STATE state;
};
Upvotes: 2
Views: 1538
Reputation: 3570
It is possible to retrieve the hash function from an std::unordered_set
and use it to find the hashed value of a key.
size_t h = myset.hash_function()("hello world");
Would the hash be the same if I run my program and insert 20 values into errorStates and when I run the program and insert 200?
The default hash function for a std::unordered_set<T>
is std::hash<T>
. One of the requirements for this class template states:
The value returned shall depend only on the argument k for the duration of the program. [Note: Thus all evaluations of the expression h(k) with the same value for k yield the same result for a given execution of the program. —end note ]
With h
being a std::hash<T>
and k
being a T
.
My interpretation of this is that in any single execution of the program the hash value for a particular key will be the same. However, over a sequence of runs the expression h(k)
is not required to be the same.
Therefore the number of values inserted will not change the hash value of a key, but only in one particular execution. You can't assume that the hash value of a key will remain the same over multiple executions.
Upvotes: 2
Reputation: 241931
Can I get the hash of this key?
Sure:
size_t hashval = errorState.hash_function()("File does not exist");
Would the hash for File does not exist always be the same? Would the hash be the same if I run my program and insert 20 values into errorStates and when I run the program and insert 200?
It won't change within a single run of the program. Adding thousands more elements to the std::set
will not change the hash value of any key. However, if you run the same program again, the hash values may be different (q.v. hash randomization). And if you run the program on a different machine or even with a different standard library implementation...
The idea is the hash will be the unique error id and write the hash to a file.
That won't work for two reasons:
As mentioned above, hash values may be different in two different executions of the same program. So they should not be persisted.
Hash values are not unique. It is entirely possible (and quite common) for two different keys to have the same hash value. This is called "hash collision". (See "birthday paradox").
Upvotes: 1