STL中最有用的经验总结(三)

好了,现在给你一个任务。把一系列字符串依次插入到一个set中,然后按照字典序有序的输出。好吧,为了突出重点,我把这些字符串规定为“Anteater”、“Wombat”、“Lemur”、“Penguin”。

你觉得很简单,所以你这样写了。

set<string*> ssp;
	ssp.insert(new string("Anteater"));
	ssp.insert(new string("Wombat"));
	ssp.insert(new string("Lemur"));
	ssp.insert(new string("Penguin"));
	for(set<string*>::iterator it=ssp.begin();it!=ssp.end();++it)
	{
		cout<<*it<<endl;
	}
结果是:


这不奇怪,new string("XXX")返回的是指向该串首地址的地址值,所以set中存的也是这些十六进制的地址,在输出set内容的时候(cout<<*it<<endl;)自然就输出如上内容了。也许你会这样修改

cout<<**it<<endl;
这当然输出了字符串的值,但是却不一定是按照字典序输出的
.

首先明确一点,set中是按节点值有序插入的,在遍历的时候也是采用中序遍历按照节点值从顺序输出。但是注意,这里的节点值是字符串首地址值而不是字符串的值。所以输出不一定能得到正确的字典序。

那应该怎么办呢?

我们知道set<string*> ssp其实是set<string*,less<string*>>ssp的简写,为了完全准确,其实应该是set<string*,less<string*>,allocator<string*>>ssp的简写,这里分配器与我们无关,故忽略。

less<string*>其实就是一个仿函数,用于人为规定set的比较规则。因此我们可以这样修改:

//添加仿函数,人为定义比较规则
struct StringLess:public binary_function<const string*,const string*,bool>
{
	bool operator()(const string*ps1,const string *ps2)const
	{
		return *ps1<*ps2;
	}
};

//重写插入操作

	set<string*,StringLess> ssp;
	ssp.insert(new string("Anteater"));
	ssp.insert(new string("Wombat"));
	ssp.insert(new string("Lemur"));
	ssp.insert(new string("Penguin"));
	for(set<string*,StringLess>::iterator it=ssp.begin();it!=ssp.end();++it)
	{
		cout<<**it<<endl;
	}

结果为:

解释两点:

1)为什么必须要用仿函数而不是用函数指针呢?

因为这和set的参数类型不匹配,set要求传入的是一个类型而不是一个函数。

2)为什么要继承binary_function<const string*,const string*,bool>呢?

其实不继承也能得到正确答案。继承的好处在于......等我看明白了《条款40:使仿函数类可适配》再告诉你吧~~

关联容器中的map也支持自定义仿函数比较方法,这里就一笑而过了吧~

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值