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!