I have the following code to make an unordered_set<Interval>
. This compiles fine.
struct Interval { unsigned int begin; unsigned int end; bool updated; //true if concat. initially false int patternIndex; //pattern index. valid for single pattern int proteinIndex; //protein index. for retrieving the pattern }; struct Hash { size_t operator()(const Interval &interval); }; size_t Hash::operator()(const Interval &interval){ string temp = to_string(interval.begin) + to_string(interval.end) + to_string(interval.proteinIndex); return hash<string>()(temp); } unordered_set<Interval, string, Hash> test;
However, I cannot compile when I try to insert using this code:
for(list<Interval>::iterator i = concat.begin(); i != concat.end(); ++i){ test.insert((*i)); }
Moreover, I cannot determine what the problem is from the error messages, for example:
note: candidate is: note: size_t Hash::operator()(const Interval&) note: candidate expects 1 argument, 2 provided
I thought I only provided 1 argument...
What is the problem with my insertion code?
Here's the new instantiation code: unordered_set<Interval, Hash> test;
However, I'm still receiving a slew of error messages, for example:
note: candidate is: note: size_t Hash::operator()(const Interval&) <near match> note: no known conversion for implicit ‘this’ parameter from ‘const Hash*’ to ‘Hash*’
An unordered_set is implemented using a hash table where keys are hashed into indices of a hash table so that the insertion is always randomized.
An unordered set of pairs is an unordered set in which each element is a pair itself. By default, C++ doesn't allow us to create an unordered set of pairs directly but one can pass a hash function to the unordered set container.
The unordered_map::hash_function() is a built in function in C++ STL which is used to get the hash function. This hash function is a unary function which takes a single argument only and returns a unique value of type size_t based on it.
We can use it to hash integers, floats, pointers, strings, arrays, pairs, and standard containers. That's all about using pair as a key in std::unordered_set in C++.
First problem:
You are passing string
as the second template argument for your instantiation of the unordered_set<>
class template. The second argument should be the type of your hasher functor, and std::string
is not a callable object.
Perhaps meant to write:
unordered_set<Interval, /* string */ Hash> test; // ^^^^^^^^^^^^ // Why this?
Also, I would suggest using names other than begin
and end
for your (member) variables, since those are names of algorithms of the C++ Standard Library.
Second problem:
You should keep in mind, that the hasher function should be qualified as const
, so your functor should be:
struct Hash { size_t operator() (const Interval &interval) const { // ^^^^^ // Don't forget this! string temp = to_string(interval.b) + to_string(interval.e) + to_string(interval.proteinIndex); return (temp.length()); } };
Third problem:
Finally, if you want std::unordered_set
to be able to work with objects of type Interval
, you need to define an equality operator consistent with your hash function. By default, if you do not specify any type argument as the third parameter of the std::unordered_set
class template, operator ==
will be used.
You currently do not have any overload of operator ==
for your class Interval
, so you should provide one. For example:
inline bool operator == (Interval const& lhs, Interval const& rhs) { return (lhs.b == rhs.b) && (lhs.e == rhs.e) && (lhs.proteinIndex == rhs.proteinIndex); }
Conclusion:
After all the above modifications, you can see your code compiling in this live example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With