一。标准库定义的函数对象:
标准库定义了一组用于算术、关系、逻辑运算的函数对象类,他们都是类模板,定义在头文件functional中;
1. 在这里举一个算术函数对象类型的例子:plus
要对数值1和2进行加法运算,可以写如下代码:
plus
int sum = add(1, 2); //调用了类模板plus定义的调用操作符函数;
2. 将标准库函数对象应用于算法,用到二元函数对象greater
例如,对vector 中的元素从大到小排序:
int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
vector
sort(ivec.begin(), ivec.end(), greater
二元函数对象返回的真假值,是第一个参数相对于第二个参数的结果,即第一个参数小于,等于,或大于第二参数,则返回真值;
二。函数适配器:
对于上述例子,如果在vector中查找大于5的所有元素,我们可以使用算法find_if,但是find_if的第三个参数为一个接受一个形参的函数,而且find_if只传递一个实参到函数对象,但是函数对象greator
find_if(ivec.begin(), ivec.end(), greater
现在遇到的问题就是如何将接受两个形参的函数对象转换为接受一个形参的函数对象,以及如何指定被比较的数值5,于是函数适配器产生了:
函数适配器就是通过将一个操作数绑定到给定值而将二元函数对象转换为一元函数对象,函数适配器分为两类:绑定器 与 求反器;
1. 绑定器:bind1st:将给定值绑定到二元函数对象的第一个实参; bind2nd:将给定值绑定到二元函数对象的第二个实参;他们的返回值都是一元函数对象;
此例中,可以将数值5绑定到二元函数对象greater
vector
while((ite = find_if(ite, ivec.end(), bind2nd(greater
{
cout << *ite << " ";
ite++;
}
bind2nd返回一个一元函数对象,根据greater
此例也可以使用适配器 bind1st 与 函数对象less
2. 求反器:not1:对一元函数对象的结果取反; not2:对二元函数对象的结果取反;
//如下语句功能是统计小于等于5的元素个数,用到了表示 <= 的函数对象less_equal
size_t n1 = count_if(ivec.begin(), ivec.end(), bind2nd(less_equal
如果改为统计不小于等于5的元素个数,修改语句如下:
size_t n1 = count_if(ivec.begin(), ivec.end(), not1(bind2nd(less_equal
因为bind2nd返回的是一元函数对象,所以使用not1,而不是not2;
全部代码:
#include
#include
#include
using namespace std;
int main()
{
int a[] = {1, 2, 3, 4, 5, 6, 7, 8};
vector
size_t n1 = count_if(ivec.begin(), ivec.end(), bind2nd(less_equal
cout << "n1:" << n1 << endl;
//size_t n = count_if(ivec.begin(), ivec.end(), not1(bind2nd(less_equal
size_t n2 = count_if(ivec.begin(), ivec.end(), bind1st(less_equal
cout << "n2:" << n2 << endl;
less_equal
size_t n3 = le(5, 8);
cout << "n3:" << n3 << endl;
vector
while((ite = find_if(ite, ivec.end(), bind2nd(greater
{
cout << *ite << " ";
ite++;
}
cout << endl;
sort(ivec.begin(), ivec.end(), greater
while(ite != ivec.end())
{
cout << *ite << " ";
ite++;
}
cout << endl;
}
运行结果:
n1:5
n2:4
n3:1
6 7 8