概念:
本质: 函数对象(仿函数)是一个类,不是一个函数
特点:
代码示例:
//1、函数对象在使用时,可以像普通函数那样调用, 可以有参数,可以有返回值
class MyAdd
{
public:int operator()(int v1, int v2)//有参数,有返回值{return v1 + v2;}
};void test1()
{MyAdd myadd;//创建函数对象cout << "函数对象特点1:类似普通函数的调用,有参数、有返回值" << endl;cout << "myadd = " << myadd(10, 20) << endl;cout << string(50, '-') << endl;
}//2、函数对象超出普通函数的概念,函数对象可以有自己的状态
class MyPrint
{
public:MyPrint(){this->count = 0;//初始化为0}void operator()(string test){cout << test << endl;this->count++;//调用一次就记录一次}int count;//内部自己状态
};void test2()
{MyPrint myprint;//创建函数对象cout << "函数对象特点2:函数对象可以有自己的状态" << endl;myprint("Keep working out!");//函数对象调用myprint("Keep fitting!");myprint("Keep slenderizing!");cout << "myprint调用次数为:" << myprint.count << endl;cout << string(50, '-') << endl;
}//3、函数对象可以作为参数传递
void doPrint(MyPrint& myprint, string test)
{myprint(test);
}void test3()
{MyPrint myprint;//创建函数对象cout << "函数对象特点3:函数对象作为参数传递" << endl;doPrint(myprint, "Bella要减肥");//函数对象作为参数传递cout << string(50, '-') << endl;
}

函数对象的特点1,其实在之前的学习笔记中有使用过,比如在list容器、set容器和map容器这几个容器的自定义数据类型排序以及内置数据类型的降序排序都使用过。
对于特点2,普通函数没有函数对象这样可以有成员属性来记录本身的状态,比如统计函数的调用次数,因为函数对象本质是一个类,类是可以有成员属性的。
对于特点3,函数对象可以做为一个参数传递。
总结: 仿函数写法非常灵活,可以作为参数进行传递。
概念:
代码示例:
class LargerthanSix
{
public:bool operator()(int val)//布尔类型的仿函数{return val > 6;}
};void test1()
{vector v;for (int i = 0; i < 10; i++){v.push_back(1 + i);}//在容器中找是否有大于6的元素可以用find_if//LargerthanSix() 创建匿名的函数对象(仿函数)vector::iterator it = find_if(v.begin(), v.end(), LargerthanSix());//输出全部大于6的结果for (; it != v.end(); it++){cout << "比6大的数有:" << *it << endl;if (it == v.end()){cout << "没有比6大的数!" << endl;break;}}
}

注意点:
首先,find_if函数的第一个和第二个参数是迭代器,表示一个区间中查找;第三个参数是仿函数,如果看到pred表示需要传入一个仿函数,下图示

其次,选中find_if→右键→转到定义 查看源码,find_if的返回值是一个迭代器

以上是find_if源码,说明如下
总结: 参数只有一个的谓词,称为一元谓词
示例:
class Mysort
{
public:bool operator()(int v1, int v2)//布尔类型的仿函数{return v1 > v2;}
};void test1()
{vector v;v.push_back(30);v.push_back(18);v.push_back(28);v.push_back(23);v.push_back(25);v.push_back(26);cout << "标准算法sort排序 升序\nv: ";sort(v.begin(), v.end());for(vector::iterator it=v.begin();it!=v.end();it++){cout << *it << " ";}cout << endl << string(40, '-') << endl;//使用函数对象 改变算法排序规则 降序cout << "\n制定算法sort排序 降序\nv: ";sort(v.begin(), v.end(), Mysort());//Mysort() 匿名对象for (vector::iterator it = v.begin(); it != v.end(); it++){cout << *it << " ";}cout << endl << string(40, '-') << endl;
}

这个sort算法当中需要的是一个谓词,因此仿函数是bool类型。

总结: 参数只有两个的谓词,称为二元谓词
上一篇:前端工程师leetcode算法面试必备-二分搜索算法(上)
下一篇: 最新或2023(历届)金华市集体户口孩子落户办理流程及迁移手续【完整版】 金华市户口迁入办理流程 外地户口迁入金华市在哪里办