《白话C++》第10章 Page133 常用容器 10.6.5 std::set和std::multiset

1.基本概念与基础用法

vector,deque,list  这类容器内部的元素的(逻辑)存储次序, 由各元素插入选择的位置共同决定,调用一个push_back()插入新元素,新元素就肯定是在容器的尾部,除非事后我们调用sort操作。

但有时候我们希望一个容器能够依据某种规则,维护数据的有序性。

set和multiset都会根据既定的排序准则,在数据插入时,自动将元素排序,

multiset允许大小相等的两个元素加入,

set不允许

测试表明:

一是multiset确实会自动将元素排序,

二是multiset确实允许输入大小一样的两个元素。

multiset默认对两个元素使用“<”比较大小,小排前,大排后,所以本例需要为自定义类型Student提供“<”的重载。

【课堂作业】:结合multiset复习 “<” 操作符重载

请修改本例,实现如果身高相同,则按姓名排序(考虑极端情况,请仍然使用multiset)。

multiset默认采用“<”比较,但也允许我们在模板实例化时,提供自定义排序时使用的比较判断式:

//Compare: 自定义的比较判断,注意:是类的名字
multiset <T, Compare>; 

如果想让学生从高排到低,粗暴的做法是认为地将  Student  中的 “<” 操作符返回  “反逻辑” ,符号是“小于号”,但比较结果是 “大于” 的判断。那样太坑爹了。

为Student写一个“>”重载?不行,sets不会聪明到你写一个大于比较符重载,它就自动在内部改用大于判断,我们还是需要写一个判断式,作为第二个模板参数传入。

但注意,之前我们碰上的“判断式”,都是作为一个对象,传递给某个函数,

sets所需要的“比较判断”是模板参数,它需要一个“类名(typename)”。普通函数胜任不了,我们必须写“函数对象”:

Student类:

函数对象:

 

 以上代码插在Student的定义之后,然后将上例中22行代码

修改为:

现在,学生可以从高排到低了。

提供包括“比较判断式类”在内的模板参数后,一个sets模板产生一个具体的sets类,那么这个类是不是只能构造出采用一模一样的排序规则的sets对象呢?不是。

sets在构造对象时,还允许我们传入具体的函数对象。比如我们让“is_taller_then”复杂一些,实现比较身高时,可以选择是否考虑姓名的因素:

接着,原023行的类型定义不变:

typedef multiset <Student, is_taller_then> SetT;

但025行构造sets对象时,传入一个特定的is_taller_then对象:

bool with_name = true;
//定制的 is_taller_then 一个对象作为入参
SetT sets(is_taller_then(with_name))

【课堂作业】:身高视力排座

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值