函数对象(仿函数)的相关基本概念及用法

函数对象(仿函数)

基本概念

重载函数调用操作符的类,其对象称为函数对象

函数对象使用重载的()时,行为类似函数调用,因此也被称为仿函数

本质

函数对象(仿函数)是一个类,而不是一个函数!!!

函数对象(仿函数)的使用

特点:

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是一元运算(即只有一个操作数),其他都是二元运算

函数对象(仿函数)的相关基本概念及用法_第1张图片

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;
}

关系防函数

功能描述:

通过内置的仿函数,实现关系对比。

函数对象(仿函数)的相关基本概念及用法_第2张图片

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类似,理解掌握即可

逻辑仿函数

用于实现逻辑运算

函数对象(仿函数)的相关基本概念及用法_第3张图片

逻辑仿函数实际应用较少,了解即可

 

你可能感兴趣的:(c++,算法,开发语言)