2、set 和 multiset 插入数据特点不同的原因
上面提到二者的不同点在于是否可以插入不同的数据,那么就来看看二者insert插入方法的源码
2.1、set 中的insert 源码分析
查看set 中的insert 源码:
可以看到这里的insert返回值类型是一个pair二元组,包含迭代器类型和布尔类型
那么再进行插入操作的时候,如果检查到容器中已经有相同元素,就会返回false,不进行插入
有关二元组的创建将在下面解释
2.2、pair 对组的创建及使用
功能描述:
成对出现的数据,利用对组可以返回两个数据
两种创建方式:
pair<type, type> p ( value1, value2 );
pair<type, type> p = make_pair( value1, value2 );
代码示例:
// pair 对组的使用 make_pair() void testPair() { // 默认构造 pair<string, int> pre("微凉", 10); pair<string, int> ptr = make_pair("秋意", 24); // 获取值 cout << pre.first << ptr.first << "\n" << pre.second << ptr.second << endl; }
推荐使用make_pair的方式创建二元组,这样看起来比较清晰
二元组通过调用first和second来访问对应的属性值
2.3、multiset 中的insert 源码分析
查看multiset 中的insert 源码:
multiset 中的insert 返回值类型是一个迭代器,并没有布尔类型
所以可以插入重复数据
3、内置与自定义数据类型的排序规则
set 容器插入时默认自动升序排序,那么怎么修改排序规则呢:
使用仿函数来指定排序规则
3.1、内置数据类型的排序
写一个类,重载类内的函数运算符() :
// 修改 set 容器的排序规则 class Cmp { public: bool operator()(int v1,int v2) const { return v1 > v2; } }; void test7() { // 默认是升序 set<int> s1; s1.insert(1); s1.insert(0); s1.insert(2); s1.insert(4); printSet(s1); // 修改为降序,借助仿函数 set<int, Cmp> s2; s2.insert(1); s2.insert(0); s2.insert(2); s2.insert(4); for (auto it = s2.begin(); it != s2.end(); it++) { cout << *it << " "; } }
要注意的是重载的函数需要是常函数,要加上const关键字
重载的细节可以参考我这篇博客:详解重载函数调用运算符
创建set 容器的时候就要指定排序规则,在尖括号中这样表示:set<int, Cmp>
3.2、自定义数据类型的排序
set 容器插入自定义数据的时候如果不指定排序规则,默认的升序排序也无法进行,因此需要事先指定排序规则:
// 定义Person 类 class Person { int age; string name; public: Person(string name, int age) { this->name = name; this->age = age; } int getAge() const { return this->age; } string getName() const { return this->name; } }; // 自定义排序规则 class Compare { public: bool operator()(const Person &p1, const Person &p2)const { return p1.getAge() > p2.getAge(); } }; void test8() { set<Person, Compare> s; Person p1("叶落", 20); Person p2("微凉", 24); Person p3("秋意", 22); Person p4("秋白", 18); s.insert(p1); s.insert(p2); s.insert(p3); s.insert(p4); for (auto it = s.begin(); it != s.end(); it++) { cout << "姓名:" << it->getName() << "\t年龄:" << it->getAge()<<endl; } }
运行效果:
自定义数据类型重载时的要求比较严格:
不仅函数需要加const限制,参数列表中也都要加const
由于Person类中的属性采用了封装,那么在对应的get 方法中也要是常函数
希望以此文章帮助大家快速学会、复习set容器的使用,创作不易,希望大家能够点赞支持!