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.