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; }
The unordered_set::insert() is a built-in function in C++ STL which is used to insert a new {element} in the unordered_set container. Each element is inserted only if it is not already present in the container (elements in an unordered_set have unique values).
An unordered_set is an Associative container that contains an unordered set of data inserted randomly. Each element may occur only once, so duplicates are not allowed. A user can create an unordered set by inserting elements in any order and an unordered set will return data in any order i.e. unordered form.
The difference between an unordered_map and an unordered_set is that an unordered_map stores data only in the form of key-value pair while an unordered_set can store data that is not necessarily in the form of key-value pairs (example integer, string, etc.).
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.
Since this is the top Google result on Stack Overflow for C++ unordered_set of objects
I'll post a simple yet completely illustrative and copy/paste runnable example:
// UnorderedSetOfObjects.cpp #include <iostream> #include <vector> #include <unordered_set> struct Point { int x; int y; Point() { } Point(int x, int y) { this->x = x; this->y = y; } bool operator==(const Point& otherPoint) const { if (this->x == otherPoint.x && this->y == otherPoint.y) return true; else return false; } struct HashFunction { size_t operator()(const Point& point) const { size_t xHash = std::hash<int>()(point.x); size_t yHash = std::hash<int>()(point.y) << 1; return xHash ^ yHash; } }; }; int main(void) { std::unordered_set<Point, Point::HashFunction> points; points.insert(Point(1, 1)); points.insert(Point(2, 2)); points.insert(Point(1, 1)); // notice this is a duplicate with the 1st point so it won't change the set std::cout << "points: " << "\n"; for (auto& point : points) { std::cout << "(" << point.x << ", " << point.y << ")" << "\n"; } return 0; }
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).
struct node_hash { std::size_t operator()(const node& _node) const { return std::hash<std::string>()(_node.node_id); } } // ... std::unordered_set<node, node_hash> node_set;
However, as one of the comments points out, you may be better off using a std::unordered_map<std::string, double>
here.
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