仿函数其作用和函数类似,但是,表现形式却是类。在容器以及排序过程中,可以用仿函数提供排序的依据。
今天琢磨了一下午,总算把仿函数的用法弄清楚了一点。此文为个人总结,不保证没有错误的地方。
1.在关联容器的定义过程中,自定义compare函数。由于是出现在定义过程中,用于指定关联容器模板类型,所以,参数一定时类型而不是具体的对象。
以map为例:
template < class Key, class T, class Compare = less, class Allocator = allocator > > class map;
map容器在定义过程中,可以指定4个参数,第三个默认为less函数,而且是以Key作为排序对象。其实,第三个参数可以自行设定函数,但都是要以Key作为比较对象才可以。
第三个参数可以用仿函数实现,也可以为函数。
1)仿函数的定义形式以及定义map的形式
此处需要注意第三个参数的调用形式,是一种类型,而不是指具体的对象,加()是不对的
struct cmp
{
bool operator()(const string &lhs,const string &rhs)
{
return lhs<rhs;
}
};
map<string,int,cmp> namescore;//OK
map<string,int,cmp()> namespace;//ERROR
2)直接用函数
直接用函数的话,由于map在定义时,要指定模板的数据类型,所以,第三个参数表示为特定的函数类型(切记不是具体的函数)
bool compare( const string &lhs, const string &rhs)
{
return lhs<rhs;
}
<pre name="code" class="cpp">bool (*fn_pt)(const string&,const string&) = compare;
map<string,int,bool(*)(const string&,const string&)> namescore;
map<string,int,bool(*)(const string&,const string&)>::iterator itr=namescore.begin();//OK
map<string,int,compare> ::iterator itr;//ERROR
2.在泛型算法sort中
1)仿函数
sort函数的调用过程中,参数都为具体的对象,所以,要加()
class HighToLow
{ public:
bool operator()(const PAIR& lhs, const PAIR& rhs)
{
return rhs.second<lhs.second;
}
};
vector<pair<string,int>> nameScore;
sort(nameScore.begin(),nameScore.end(),HighToLow());//OK
<pre name="code" class="cpp">sort(nameScore.begin(),nameScore.end(),HighToLow);//ERROR
2)函数
sort的第三个参数为指向函数的指针,所以,用具体的函数对象作为实参
bool HighToLow(const PAIR& lhs, const PAIR& rhs)
{
return lhs.second> rhs.second;
}
<pre name="code" class="cpp">sort(nameScore.begin(),nameScore.end(),HighToLow);//OK
总结:
对于仿函数和函数作为compare出现,要特别注意出现的场合,尤其需要分清楚是需要类型还是需要具体对象。调用的方式很容易出错!