重载函数调用操作符的类,其对象称为函数对象
函数对象使用重载的()时,行为类似函数调用,因此也被称为仿函数
本质
函数对象(仿函数)是一个类,而不是一个函数!!!
特点:
1、函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
2、函数对象超出普通函数的概念,函数对象可以有自己的状态
3、函数对象可以作为参数传递(因为函数对象本身就是一个实例化的对象,因此可以作为参数)
eg:
#include
using namespace std;
#include
//1、1、函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
class functionAdd
{
public:
int operator()(int a,int b)//重载函数调用操作符,用于实现加法运算
{
return a + b;
}
};
//2、函数对象超出普通函数的概念,函数对象可以有自己的状态
class funcPrint {
public:
void operator()(string test)//重载函数调用操作符,用于打印传入的字符
{
cout << test << endl;
count++;//每次调用重载()都会使count++
}
int count=0;//统计调用此函数对象的次数
};
void test01()
{
funcPrint fp;//实例化函数对象
//需求:统计调用了多少次此仿函数
fp("hello world");
fp("hello world");
fp("hello world");
fp("hello world");
fp("hello world");
cout << "此函数对象调用的次数为:" << fp.count << endl;
}
//3、函数对象可以作为参数传递(因为函数对象本身就是一个实例化的对象,因此可以作为参数)
void doPrint(funcPrint &fp,string test)
{
fp(test);//相当于间接调用函数对象进行打印
}
int main()
{
functionAdd f;//实例化函数对象
cout<
注:参数列表中加了const和没加const是两种不同的参数列表,即若仿函数实现的参数列表中无const修饰,但实现函数调用时却用了const修饰,则编译器会找不到与参数列表和对象匹配的函数
eg:
class funcPrint {
public:
void operator()(string test)//重载函数调用操作符,用于打印传入的字符
{
cout << test << endl;
}
};void doPrint(const funcPrint &fp,string test)//错误
{
fp(test);
}void doPrint(funcPrint &fp,string test)//正确
{
fp(test);//相当于间接调用函数对象进行打印
}
返回bool类型的仿函数就称为谓词
如果operator()接受一个参数,就叫做一元谓词
如果operator()接受两个参数,就叫做二元谓词
eg:
需求:找出容器中大于5的数
#include
using namespace std;
#include
#include
class GreaterFive {//一元谓词
public:
bool operator()(int val)
{
return val > 5;//当val大于5时返回true,即满足需求
}
};
int main()
{
vectorv;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
//GreaterFive()是一个匿名对象,find_if第一、二、三个参数分别填需遍历容器的起始位置、终止位置以及实例化的函数对象
vector::iterator it;
it=find_if(v.begin(), v.end(),GreaterFive() );//若找到,则find_if会返回指向该元素的迭代器,否则返回v.end()
if (it == v.end())
{
cout << "容器中无比5大的元素" << endl;
}
else
{
cout << "容器中第一个比5大的元素为: " << *it << endl;
}
return 0;
}
eg:
#include
using namespace std;
#include
#include
bool compare(int left,int right)
{
return left > right;
}
class Greater {
public:
bool operator()(int left, int right)
{
return left > right;
}
};
int main()
{
vectorv;
for (int i = 0; i < 10; i++)//升序插入
{
v.push_back(i);
}
//用改变sort的排序规则,使其变为降序排列---可以使用函数实现,当然也可以用二元谓词实现
sort(v.begin(), v.end(), Greater());//Greater()是一个匿名的函数对象
for (vector::iterator it = v.begin(); it != v.end(); it++)//遍历动态数组
{
cout << *it << " ";
}
cout << endl;
return 0;
}
STL中提供了一些仿函数模板对数据进行相应的处理,处理数据时仅需调用相应的仿函数就可以,大大减小了无意义的工作,为写代码提供了便利。
分类:
内建的函数对象分为算数仿函数、关系仿函数、逻辑仿函数
用法:
1、这些仿函数所产生的对象,用法和一般函数完全相同。
2、使用内建函数对象,需要包含头文件即#include
功能描述:
1、实现四则运算
2、其中negate是一元运算(即只有一个操作数),其他都是二元运算
eg:
#include
using namespace std;
#include
int main()
{
//其他二元运算同理
plusp;//对象实例化--创建一个int类型的一个函数对象
int ret=p(10, 20);//将10与20相加,函数返回结果用ret接收
cout << ret << endl;
negaten;//注意实例化对象时需要知名模板参数的类型
ret=n(50);//对50取反操作
cout << ret << endl;
return 0;
}
功能描述:
通过内置的仿函数,实现关系对比。
eg:
#include
using namespace std;
#include
#include
#include
class Greater {//此仿函数即为greater的实现原理
bool operator()(int left, int right)
{
return left > right;
}
};
int main()
{
vectorv;
for (int i = 0; i < 10; i++)
{
v.push_back(i);
}
//greater()---greater是STL提供的内置仿函数模板,用于指代模板参数类型,greater()即用于创建一个匿名对象用于实现降序排列
sort(v.begin(), v.end(), greater());//实现容器降序排列
for (vector::iterator it = v.begin(); it != v.end(); it++)//编列动态数组
{
cout << *it << " ";
}
cout << endl;
return 0;
}
注:1、sort函数之所以默认是升序排列,就是因为sort函数第三个参数默认为less(即小于仿函数)
2、greater在实际应用中使用较多,其他关系仿函数的应用与greater类似,理解掌握即可
用于实现逻辑运算
逻辑仿函数实际应用较少,了解即可