std::set example: In the previous article, we have discussed about How to Iterate over a map in C++. Let us learn about std::set Example and Tutorial with User Defined Classes in C++ Program.
std::set Example and Tutorial
C++ std set example: In this article, we will learn to use std::set with user defined classes.
We will overload operator < in the class to use std::set with user defined classes and also to implement default sorting criteria.
Let our class is MsgInfo which contains the following three properties,
- Message content
- Message sender
- Message receiver
#include<iostream>
#include<set>
#include<string>
class MsgInfo
{
public:
std::string msgCont;
std::string msgSender;
std::string msgReceiver;
MsgInfo(std::string sender, std::string receiver, std::string msg) :
msgCont(msg), msgSender(sender), msgReceiver(receiver)
{}
bool operator< (const MsgInfo & msgOb) const
{
std::string rightStr = msgOb.msgCont + msgOb.msgSender + msgOb.msgReceiver;
std::string leftStr = this->msgCont + this->msgSender + this->msgReceiver;
return (leftStr < rightStr);
}
friend std::ostream& operator<<(std::ostream& os, const MsgInfo& obj);
};
std::ostream& operator<<(std::ostream& os, const MsgInfo& obj)
{
os<<obj.msgSender<<" :: "<<obj.msgCont<<" :: "<<obj.msgReceiver<<std::endl;
return os;
}
According to the implementation of < operator in above, two MsgInfo objects will be compared based on all three properties. Let’s create 4 MsgInfo objects,
MsgInfo msg1("persA", "Hi!", "persB");
MsgInfo msg2("persA", "Hi!", "persC");
MsgInfo msg3("persC", "Hi!", "persA");
MsgInfo msg4("persA", "Hi!", "persC");
Since msg2<msg4 and msg4<msg2 both are false so msg2 and msg4 are equal. So as per current default sorting criteria i.e. operator <, std::set will treat msg4 as a duplicate of msg2.
int main()
{
std::set<MsgInfo> setOfMsgs;
MsgInfo msg1("persA", "Hi!", "persB");
MsgInfo msg2("persA", "Hi!", "persC");
MsgInfo msg3("persC", "Hi!", "persA");
// Duplicate Message
MsgInfo msg4("persA", "Hi!", "persC");
setOfMsgs.insert(msg1);
setOfMsgs.insert(msg2);
setOfMsgs.insert(msg3);
setOfMsgs.insert(msg4);
// As msg4 will be treated as duplicate so it wil not be inserted
// Iterate through the elements then set and display the values
for (std::set<MsgInfo>::iterator iter=setOfMsgs.begin(); iter!=setOfMsgs.end(); ++iter)
std::cout << *iter ;
return 0;
}
We can also keep only one message allowed per person by twp methods.
Method 1: Modify operator <, but it may hamper our previous requirements and we may don’t require to access that the operator <.
Method 2: We can form a new set and use Comparator which is a external sorting criteria.
Complete Program :
#include<iostream>
#include<set>
#include<string>
class MsgInfo
{
public:
std::string msgCont;
std::string msgSender;
std::string msgReceiver;
MsgInfo(std::string sender, std::string receiver, std::string msg) :
msgCont(msg), msgSender(sender), msgReceiver(receiver)
{}
bool operator< (const MsgInfo & msgOb) const
{
std::string rightStr = msgOb.msgCont + msgOb.msgSender + msgOb.msgReceiver;
std::string leftStr = this->msgCont + this->msgSender + this->msgReceiver;
return (leftStr < rightStr);
}
friend std::ostream& operator<<(std::ostream& os, const MsgInfo& obj);
};
std::ostream& operator<<(std::ostream& os, const MsgInfo& obj)
{
os<<obj.msgSender<<" :: "<<obj.msgCont<<" :: "<<obj.msgReceiver<<std::endl;
return os;
}
int main()
{
std::set<MsgInfo> setOfMsgs;
MsgInfo msg1("persA", "Hi!", "persB");
MsgInfo msg2("persA", "Hi!", "persC");
MsgInfo msg3("persC", "Hi!", "persA");
// Duplicate Message
MsgInfo msg4("persA", "Hi!", "persC");
setOfMsgs.insert(msg1);
setOfMsgs.insert(msg2);
setOfMsgs.insert(msg3);
setOfMsgs.insert(msg4);
// msg4 will be treated as duplicate so it will not be inserted
// iterate through the elements then set and display the values
for (std::set<MsgInfo>::iterator iter=setOfMsgs.begin(); iter!=setOfMsgs.end(); ++iter)
std::cout << *iter ;
return 0;
}
Output : persC :: persA :: Hi! persA :: persB :: Hi! persA :: persC :: Hi!