函数对象
介绍
概念:
- 重载函数调用操作符的类,其对象常称为函数对象
- 函数对象使用重载的()时,行为类似函数调用,也叫仿函数
- 函数对象(仿函数)是一个类,不是一个函数。
函数对象使用
特点:
- 函数对象在使用时,可以像普通函数那样调用, 可以有参数,可以有返回值。
- 函数对象超出普通函数的概念,函数对象可以有自己的状态。
- 函数对象可以作为参数传递。
例:
#include<iostream>
#include<string>
using namespace std;
//1、函数对象在使用时,可以像普通函数那样调用, 可以有参数,可以有返回值
class MyAdd
{
public:
int operator ()(int val1,int val2)
{
return val1+val2;
}
};
void test01()
{
MyAdd ob;
cout<<ob(10,20)<<endl;
}
//函数对象可以有自己的状态
class MyPrint
{
public:
MyPrint()
{
count=0;
}
void operator ()(string test)
{
cout<<test<<endl;
count++;//统计次数
}
int count;
};
void test02()
{
MyPrint ob1;
ob1("aaa");
ob1("aaa");
ob1("aaa");
cout<<"调用次数:"<<ob1.count<<endl;
}
//函数对象作为参数传递
void MyArr(MyPrint &mp,string test)
{
mp(test);
}
void test03()
{
MyPrint ob2;
MyArr(ob2,"bbb");
}
int main()
{
test01();
test02();
test03();
return 0;
}
总结:仿函数写法非常灵活,可以作为参数进行传递。
函数符概念
正如STL定义了容器和迭代器的概念一样,它也定义了函数概念。
- 生成器是不用参数就可以调用的函数符。
- 一元函数是用一个参数就可以调用的函数符。
- 二元函数是用两个参数就可以调用的函数符。
例如:提供给fro_each()的函数应当是一元函数,因为它每次用于一个容器元素。当然,这些概念都有相应的改进版:
- 返回bool值的一元函数是一元谓词;(如果普通函数或仿函数,有一个参数就叫一元谓词)。
- 返回bool值的二元函数是二元谓词;(如果普通函数或仿函数,有两个参数就叫二元谓词)。
一元谓词
返回bool值的一元函数是一元谓词;(如果普通函数或仿函数,有一个参数就叫一元谓词)。
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
//普通函数作为一元谓词
bool greaterThan20(int val)
{
return val>20;
}
//仿函数作为一元谓词
class MyGreaterThan20
{
public:
bool operator ()(int val)
{
return val>20;
}
};
int main()
{
vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30);
v.push_back(40);
v.push_back(50);
for_each(v.begin(),v.end(),[](int val){
cout<<val<<" ";});
cout<<endl;
//找出第一个大于20的数
vector<int>::iterator ret;
//普通函数完成
//ret=find_if(v.begin(),v.end(),greaterThan20);
//仿函数完成
ret=find_if(v.begin(),v.end(),MyGreaterThan20());
if(ret!=v.end())
{
cout<<"第一个大于20的数:"<<*ret<<endl;
}
}
二元谓词
返回bool值的二元函数是二元谓词;(如果普通函数或仿函数,有两个参数就叫二元谓词)。
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
//普通函数作为二元谓词
bool myGreater(int v1,int v2)
{
return v1>v2;
}
//仿函数作为二元谓词
class MyGreater
{
public:
bool operator ()(int v1,int v2)
{
return v1>v2;
}
};
int main()
{
vector<int> v;
v.push_back(10);
v.push_back(20);
v.push_back(30