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

函数对象(仿函数)

基本概念

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

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

本质

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

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

特点:

1、函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值

2、函数对象超出普通函数的概念,函数对象可以有自己的状态

3、函数对象可以作为参数传递(因为函数对象本身就是一个实例化的对象,因此可以作为参数)

eg:

#include <iostream>
using namespace std;
#include<string>
//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<<f(10, 10)<<endl;//f(10, 10)书写方式与函数调用及其相似test01();funcPrint fp;//实例化对象doPrint(fp,"hello C++");return 0;
}

注:参数列表中加了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 <iostream>
using namespace std;
#include<string>
#include<vector>
class GreaterFive {//一元谓词
public:bool operator()(int val){return val > 5;//当val大于5时返回true,即满足需求}
};
int main()
{vector<int>v;for (int i = 0; i < 10; i++){v.push_back(i);}//GreaterFive()是一个匿名对象,find_if第一、二、三个参数分别填需遍历容器的起始位置、终止位置以及实例化的函数对象vector<int>::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 <iostream>
using namespace std;
#include<vector>
#include<algorithm>
bool compare(int left,int right)
{return left > right;
}
class Greater {
public:bool operator()(int left, int right){return left > right;}
};
int main()
{vector<int>v;for (int i = 0; i < 10; i++)//升序插入{v.push_back(i);}//用改变sort的排序规则,使其变为降序排列---可以使用函数实现,当然也可以用二元谓词实现sort(v.begin(), v.end(), Greater());//Greater()是一个匿名的函数对象for (vector<int>::iterator it = v.begin(); it != v.end(); it++)//遍历动态数组{cout << *it << " ";}cout << endl;return 0;
}

内建函数对象

内建函数对象的意义

STL中提供了一些仿函数模板对数据进行相应的处理,处理数据时仅需调用相应的仿函数就可以,大大减小了无意义的工作,为写代码提供了便利。

分类:

内建的函数对象分为算数仿函数、关系仿函数、逻辑仿函数

用法:

1、这些仿函数所产生的对象,用法和一般函数完全相同。

2、使用内建函数对象,需要包含头文件即#include<functional>

算术仿函数

功能描述:

1、实现四则运算

2、其中negate是一元运算(即只有一个操作数),其他都是二元运算

eg:

#include <iostream>
using namespace std;
#include<functional>int main()
{//其他二元运算同理plus<int>p;//对象实例化--创建一个int类型的一个函数对象int ret=p(10, 20);//将10与20相加,函数返回结果用ret接收cout << ret << endl;negate<int>n;//注意实例化对象时需要知名模板参数的类型ret=n(50);//对50取反操作cout << ret << endl;return 0;
}

关系防函数

功能描述:

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

eg:

#include <iostream>
using namespace std;
#include<functional>
#include<vector>
#include<algorithm>
class Greater {//此仿函数即为greater的实现原理bool operator()(int left, int right){return left > right;}
};
int main()
{vector<int>v;for (int i = 0; i < 10; i++){v.push_back(i);}//greater<int>()---greater是STL提供的内置仿函数模板,<int>用于指代模板参数类型,greater<int>()即用于创建一个匿名对象用于实现降序排列sort(v.begin(), v.end(), greater<int>());//实现容器降序排列for (vector<int>::iterator it = v.begin(); it != v.end(); it++)//编列动态数组{cout << *it << " ";}cout << endl;return 0;
}

注:1、sort函数之所以默认是升序排列,就是因为sort函数第三个参数默认为less(即小于仿函数)

2、greater在实际应用中使用较多,其他关系仿函数的应用与greater类似,理解掌握即可

逻辑仿函数

用于实现逻辑运算

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

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/454928.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式1-访问者模式

访问者模式是一种行为设计模式&#xff0c;它允许你定义在对象结构中的元素上进行操作的新操作&#xff0c;而无需修改这些元素的类。这种模式的主要思想是将算法与元素的结构分离开&#xff0c;使得可以在不修改元素结构的情况下定义新的操作。 所谓算法与元素结构分离&#x…

LabVIEW多功能接口卡驱动

LabVIEW多功能接口卡驱动 随着自动化测试系统的复杂性增加&#xff0c;对数据采集与处理的需求不断提高。研究基于LabVIEW开发平台&#xff0c;实现对一种通用多功能接口卡的驱动&#xff0c;以支持多通道数据采集及处理功能&#xff0c;展现LabVIEW在自动化和测量领域的强大能…

网络设备-H3C设备SNMP配置及监控

目录 1. 全局模式 2. 配置SNMP V2 3. 配置SNMP V3 4. 配置SNMP Trap 5. 保存配置 6. 查看配置结果 7. H3C设备监控 1. 全局模式 SNMP 的配置工作在网络设备的全局配置模式下完成&#xff0c;在进行SNMP 配置前&#xff0c;请先进入全局配置模式。 en ##进入特权模…

玩家笔记:幻兽帕鲁搭建服务器开服教程

玩转幻兽帕鲁服务器&#xff0c;阿里云推出新手0基础一键部署幻兽帕鲁服务器教程&#xff0c;傻瓜式一键部署&#xff0c;3分钟即可成功创建一台Palworld专属服务器&#xff0c;成本仅需26元&#xff0c;阿里云服务器网aliyunfuwuqi.com分享2024年新版基于阿里云搭建幻兽帕鲁服…

C++之程序内存分配方式

程序内存布局 现在的应用程序都运行在一个虚拟内存空间里&#xff0c;以32位系统为例&#xff0c;其寻址空间为 4G&#xff0c;大部分的操作系统都将4G内存空间的一部分挪给内核调用&#xff0c;应用程序无法直接 访问这一段内存&#xff0c;这一部分内核地址成为内核态空间&am…

算法特征逆向分析之-SHA256

作为信息摘要算法&#xff0c;SHA与MD5计算过程非常相似&#xff0c;这里记录一下其异同&#xff1a; 1 模数不同&#xff1a; MD5 4个64bit初始化常量 64个K SHA1 5个64bit初始化常量 4个K SHA…

时间序列预测 —— DeepAR 模型

时间序列预测 —— DeepAR 模型 DeepAR 模型是一种专门用于处理时间序列概率预测的深度学习模型&#xff0c;它可以自动学习数据中的复杂模式&#xff0c;提高预测的准确性。本文将介绍 DeepAR 模型的理论基础、优缺点&#xff0c;并通过 Python 实现单步预测和多步预测的完整…

力扣题目训练(7)

2024年1月31日力扣题目训练 2024年1月31日力扣题目训练387. 字符串中的第一个唯一字符389. 找不同401. 二进制手表109. 有序链表转换二叉搜索树114. 二叉树展开为链表52. N 皇后 II 2024年1月31日力扣题目训练 2024年1月31日第七天编程训练&#xff0c;今天主要是进行一些题训…

MySQL数据库③_MySQL数据类型和测试

目录 1. MySQL数据类型分类 1.1 类型汇总 1.2 整数类型 1.3 浮点数类型和定点数类型 1.4 字符串类型和文本类型 1.5 日期与时间类型 1.6 二进制类型 2. 有代表的类型测试 2.1 tinyint类型 2.2 bit类型 2.3 float类型 2.4 decimal类型 2.5 char和varchar类型 2.6 …

Java on VS Code 2024年1月更新|JDK 21支持!测试覆盖率功能最新体验!

作者&#xff1a;Nick Zhu - Senior Program Manager, Developer Division At Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎来到 Visual Studio Code for Java 2024年的第一期更新&#xff01;提前祝愿大家春节快乐&#xff01;在本博客中&#xff0c;我们将有…

FPS游戏穿模最强解决方案!开发一款FPS游戏射击游戏真的太简单!

FPS游戏穿模最强解决方案&#xff01;开发一款FPS游戏射击游戏真的太简单&#xff01; 2001年&#xff0c;FPS游戏老大哥《CS》横空出世&#xff0c;迅速在国内外掀起了一波FPS游戏的热潮&#xff0c;随后《CF穿越火线》在国内上线&#xff0c;一举拿下“玩家最喜爱的十大网络…

跑路页面HTML源码

简单的HTMLJSCSS&#xff0c;记事本修改内容&#xff0c;喜欢的朋友可以下载 https://download.csdn.net/download/huayula/88811984