Using Set with Comparator in C++

In this article we will see how to use external Sorting Criteria i.e. Comparator in std::set.

Suppose our class is Message that contains three properties i.e.
• Member content
• Sending User Name
• Receiving User Name

Requirement:
we want to keep only single message sent by each user i.e. only one sent message is allowed per user and we can’t modify operator <.

Solution:

Use external sorting criteria i.e. comparator

Message Class,

#include<iostream>
#include<set>
#include<string>

class Message
{
public:
	std::string m_MsgContent;
	std::string m_sentBy;
	std::string m_recivedBy;

	Message(std::string sentBy, std::string recBy, std::string msg) :
		m_MsgContent(msg), m_sentBy(sentBy), m_recivedBy(recBy)
	{}
	friend std::ostream& operator<<(std::ostream& os, const Message& obj);

};
std::ostream& operator<<(std::ostream& os, const Message& obj)
{
	os<<obj.m_sentBy<<" :: "<<obj.m_MsgContent<<" :: "<<obj.m_recivedBy<<std::endl;
	return os;
}

Now create a Message comparator,



    class MessageUserComparator
    {
    	std::string m_userName;
    public:
    	MessageUserComparator(std::string userName) :
    		m_userName(userName)
    	{}
    	bool operator() (const Message& msg1, const Message& msg2) const
    	{
    		if(msg1.m_sentBy < msg2.m_sentBy )
    			return true;
    		else
    			return false;
    	}
    };
    

    According to above implementation of comparator two Message objects are compared on the bases of all the sent user name.

    So suppose we created 4 Message objects,

    Message msg1("user_1", "Hello", "user_2");
    Message msg2("user_1", "Hello", "user_3");
    Message msg3("user_3", "Hello", "user_1");
    Message msg4("user_1", "Hello", "user_3");
    

    Here only msg1, msg2 and msg4 are equal because according to MessageUserComparator implementation.

    So, if we insert all the above objects in std::set i.e.

    	std::set<Message, MessageUserComparator> setOfMsgs;
    	Message msg1("user_1", "Hello", "user_2");
    	Message msg2("user_1", "Hello", "user_3");
    	Message msg3("user_3", "Hello", "user_1");
    	Message msg4("user_1", "Hello", "user_3");
    

    Then out of 4 only 2 will be inserted.

    Let’s use the message comparator with std::set of messages,

    int main()
    {
    
    	Message msg1("user_1", "Hello", "user_2");
    	Message msg2("user_1", "Hello", "user_3");
    	Message msg3("user_3", "Hello", "user_1");
    	Message msg4("user_1", "Hello", "user_3");
    
    	// std::set that contains the messages sent by user - "user_1"
    	std::cout<<"set that contains the messages sent by user - user_1"<<std::endl;
    	std::set<Message, MessageUserComparator> setOfMsgs_1(MessageUserComparator("user_1"));
    
    	setOfMsgs_1.insert(msg1);
    	setOfMsgs_1.insert(msg2);
    	setOfMsgs_1.insert(msg3);
    	setOfMsgs_1.insert(msg4);
    	// msg1, msg2 and msg4 are duplicates according to MessageUserComparator implementation
    	// hence only 2 element are actually inserted in std::set
    	// Iterate through all the elements in a set and display the value.
    		for (std::set<Message>::iterator it=setOfMsgs_1.begin(); it!=setOfMsgs_1.end(); ++it)
    		    std::cout << *it ;
    
    	return 0;
    }
    

    Output:
    user_1 :: user_2 :: Hello
    user_3 :: user_1 :: Hello
    Thanks.

    Scroll to Top