Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a C++ unordered_set for a custom class?

Tags:

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; } 
like image 523
daydayup Avatar asked Jul 24 '16 16:07

daydayup


People also ask

What is the use of unordered_set in C++?

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).

How does unordered_set work?

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.

What is the difference between Unordered_map and unordered_set?

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.).

Can we insert pair in unordered_set C++?

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.


2 Answers

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; } 
like image 183
cdahms Avatar answered Sep 17 '22 12:09

cdahms


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.

like image 43
sjrowlinson Avatar answered Sep 17 '22 12:09

sjrowlinson