How can I store objects of a class in an unordered_set
? My program needs to frequently check if an object exists in this unordered_set
and if it does, then do some update on that object.
I have looked up online on how to use unordered_set
, but sadly most tutorials are about using it on int
or string
types. But how can I use it on a class? How can I define a hash function to make the node_id
in the following example the key of the unordered_set
?
#include <iostream>
#include <unordered_set>
using namespace std;
// How can I define a hash function that makes 'node' use 'node_id' as key?
struct node
{
string node_id;
double value;
node(string id, double val) : node_id(id), value(val) {}
};
int main()
{
unordered_set<node> set;
set.insert(node("1001", 100));
if(set.find("1001") != set.end()) cout << "1001 found" << endl;
}
I agree to sjrowlinson that for your specific use case an
std::unordered_map<std::string, double>
might be the better choice. However, if you want to stick to anunordered_set
due to some reason, then you can also use a lambda expression instead of defining a hash function. But you also have to provide a comparison function (equal
) to make your code working. If you want twonode
instances to be equal if they have the samenode_id
, then you can use the following code:However, if you want to use
std::unordered_set::find()
, then you cannot simply provide a string (e.g."1001"
) to that function, because it expects anode
object as parameter. The following code (which creates a temporary object) does the trick, though:Please note that the output
1001 found
is printed, although thevalue
of the insertednode
is different from thevalue
of thenode
given to thefind()
function (100 and 0, respectively). This is, because the comparison functionequal
only considers thenode_id
when checking for equality.Code on Ideone
You need to implement a custom hash function (I'd suggest using the function in the Boost library) to do this. C++ allows you to save pointers to objects of a class using unordered_set. For most purposes, that should do the trick.
You could try using the following hash function object (it's pretty basic so you may want to improve it to avoid too many collisions).
However, as one of the comments points out, you may be better off using a
std::unordered_map<std::string, double>
here.