先弄清几个概念,什么叫一元函数,二元函数
1. 一元函数一个参数
2. 二元函数
两个参数
3. 一元谓词 一个参数,返回类型为bool型
4. 二元谓词 两个参数,返回类型为bool型
函数适配器是用来让一个函数对象表现出另外一种类型的函数对象的特征。因为,许多情况下,我们所持有的函数对象或普通函数的参数个数或是返回值类型并不是我们想要的,这时候就需要函数适配器来为我们的函数进行适配
C++中有三类适配器,分别是容器适配器,迭代器适配器和函数适配器,这里主要介绍函数适配器。
函数适配器用于特化和扩展一元二元函数对象,函数适配器主要有以下两类:
1 绑定器
该类适配器用于将二元函数适配成一元函数
将二元函数的一个参数绑定到一个特定的值上,将二元函数对象转换成一元函数对象。
绑定器适配器有两种:bind1st bind2nd。每个绑定器接受一个函数对象和一个值
bind1st将给定值绑定到二元函数对象的第一个实参
bind2nd将给定值绑定到二元函数对象的第二个实参
例子:
先看下count_if的普通用法
count_if:
利用输入的函数,对标志范围内的元素进行比较操作,返回结果为true的个数。例如:vecInt是用vector<int>声明的容器,已包含1,3,5,7,9元素,现要求求出大于等于3的元素个数
bool GreaterThree(int iNum)
{
if(iNum>=3)
{
return true;
}
else
{
return false;
}
}
int iCount = count_if(vecIntA.begin(),vecIntA.end(), GreaterThree);
//这里要求GreaterThree的函数参数必须是一个
//此时iCount == 4count_if(vec.begin(), vec.end(), bind2nd(less_equal<int>(), 10));
// less_equal<int>()函数是两个参数,怎样让他变成一个参数呢?
less_equal是STL为我们提供的一个函数对象,它有两个参数,其作用是比较第一个参数值是否<=第二个参数值。但是count_if要求我们第三个参数必须是一个一元谓词(就是只有一个参数),所以我们用bind2nd对该函数对象进行适配,将10绑定到该函数对象的第二个参数上。
(意思就是说less_equal<int>( _Left, _Right)这个函数只要他的第二个参数,第一个参数忽略)
现在cont_if执行的功能实际上就变成了查找给定序列中值<=10的元素的个数
2 取反器 将函数对象的结果真值求反
取反器有两种:not1和not2
not1是对一元函数对象求反的取反器,传递给函数对象的只有一个参数,则要使用这个not1
not2是对二元函数对象求反的取反器
例子
int* where=find_if(&array[0],&array[100],not1(bind2nd(breater<int>(),200)))
推荐一个很好的判断传参的方法:先写一个类,重载()算符,并接受传递进来的参数,判断后再返回真假
例子:
#include <functional>
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <cassert>
#define ASSERT assert
using namespace std;
class Rand:public binary_function<int, int, int>
{
public:
Rand()
{ srand((unsigned int)time(NULL)); }
int operator()(int minval, int maxval) const
{
ASSERT(maxval>minval);
ASSERT(minval>=0);
ASSERT(maxval<=RAND_MAX);
return (rand()%(maxval-minval)) + minval;
}
};
int main()
{
cout<<Rand()(1,5)<<endl; //[1,5)
cout<<bind1st(Rand(),20)(30)<<endl;
return 0;
}
C++函数适配器