In the previous article, we have discussed about C++ Map : Operator [] – Usage Details. Let us learn Map Tutorial in C++ Program.
Using User defined class objects as keys in std::map
In this article, we are going to see how we can use user defined class objects as keys in the std::map
.
The std::map
by default uses the < operator
to sort the keys however it is not available for user defined classes.
So, for the user defined classes we should have a default sorting criteria or we need a comparator that can compare two objects.
Overloading operator < for sorting of keys :
We are going to overload the operator < demonstrate by the following example
#include <iostream> #include <map> #include <string> class User { std::string m_identity; std::string m_text; public: User(std::string text, std::string identity) : m_identity(identity), m_text(text) { } const std::string &getId() const { return m_identity; } const std::string &getText() const { return m_text; } bool operator<(const User &userObj) const { if (userObj.m_identity < this->m_identity) return true; } }; //Method that sets the Class as key void example_1() { std::map<User, int> m_userInMap; m_userInMap.insert(std::make_pair<User, int>(User("Mr.A", "3"), 100)); m_userInMap.insert(std::make_pair<User, int>(User("Mr.B", "1"), 102)); m_userInMap.insert(std::make_pair<User, int>(User("Mr.A", "2"), 109)); std::map<User, int>::iterator it = m_userInMap.begin(); for (; it != m_userInMap.end(); it++) { std::cout << it->first.getText() << " :: " << it->second << std::endl; } } int main() { std::cout << "EX 1 :: Comparing ID" << std::endl; example_1(); return 0; }
Output : EX 1 :: Comparing ID Mr.A :: 100 Mr.A :: 109 Mr.B :: 102
In the above example we can see two objects of the user defined class and one duplicate as we assigned two values to the same key i.e. Mr. A.
In case we want to change the sorting criteria for the keys, we can either modify the definition of the operator < or we can use external comparators.
Using Comparator for sorting of keys :
#include <iostream> #include <map> #include <string> class User { std::string m_identity; std::string m_text; public: User(std::string text, std::string identity) : m_identity(identity), m_text(text) { } const std::string &getId() const { return m_identity; } const std::string &getText() const { return m_text; } bool operator<(const User &userObj) const { if (userObj.m_identity < this->m_identity) return true; } }; struct UserNameComparator { bool operator()(const User &left, const User &right) const { return (left.getText() > right.getText()); } }; void example_1() { std::map<User, int, UserNameComparator> m_userInMap; m_userInMap.insert(std::make_pair<User, int>(User("Mr.A", "3"), 100)); m_userInMap.insert(std::make_pair<User, int>(User("Mr.B", "1"), 102)); m_userInMap.insert(std::make_pair<User, int>(User("Mr.A", "2"), 109)); std::map<User, int, UserNameComparator>::iterator it = m_userInMap.begin(); for (; it != m_userInMap.end(); it++) { std::cout << it->first.getText() << " :: " << it->second << std::endl; } } int main() { std::cout << "EX 1 :: Comparing ID" << std::endl; example_1(); return 0; }
Output: EX 1 :: Comparing ID Mr.B :: 102 Mr.A :: 100
Here we get only one entry for the Mr.A as we used the User objects to compare keys.