1.作为模板类型实参的仿函数
传递仿函数的一个方法是让它的类型作为一个模板实参,传递一个该类型的仿函数对象。
类型本身并不是一个仿函数,因此客户端或者客户端类都必须创建一个给定类型的仿函数对象。当前,只有class类型仿函数才能这么做,函数指针不行,而且函数指针本身也不会指定任何行为
eg: template<typename FO>---->模板类型实参
void my_sort(...)
{
FO cmp;//创建函数对象
if(cmp(x,y)){
。。。
}
}
//以仿函数为模板实参,来调用函数
my_sort(std::less<...> >(...);---》模板显式实例化传递模板实参
比较代码(std::less)的选择将会在编译器进行,并且由于比较操作是内联的,所以一个优化的编译器将能够产生本质上等价于不使用仿函数,而直接编写的代码
2.作为函数调用实参的仿函数
另一种传递仿函数的方法是以函数调用实参的形式进行传递----》传递仿函数对象
eg:
template<typename F>
void my_sort(...,F cmp)--->函数调用实参
{
if(cmp(x,y)){
.....
}
}
//以仿函数作为调用实参,调用排序函数
my_sort(...,std::less<...>());---->函数调用实参:传递对象,进行实参演绎
3.结合函数调用实参和模板类型实参
对于前面两种传递仿函数的方式---》即传递函数指针和class类型的仿函数,只需要定义缺省函数调用实参,是完全可以把这两种方式结合起来
eg:
template<typename F>
void my_sort(..., F cmp=F())
{
if(cmp(x,y){
}
}
4.作为非类型模板实参的仿函数---》函数指针作为非类型模板实参
class类型的仿函数将不能作为一个有效的非类型模板实参,我们可以让一个指向class类型对象的指针或引用作为非类型实参
注意: 在C++中,借助于引用或者指针的非类型实参必须能够和参数类型精确匹配,从派生类到基类的转型是不允许的,而进行显式类型转换也会使实参无效
总结: class类型的仿函数适合做类型模板实参进行传递,而函数指针(函数引用)却可以是有效的非类型实参