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

news2024/10/7 12:20:45

函数对象(仿函数)

基本概念

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

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

本质

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

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

特点:

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.coloradmin.cn/o/1434245.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习本科课程 大作业 多元时间序列预测

1. 问题描述 1.1 阐述问题 对某电力部门的二氧化碳排放量进行回归预测&#xff0c;有如下要求 数据时间跨度从1973年1月到2021年12月&#xff0c;按月份记录。数据集包括“煤电”&#xff0c;“天然气”&#xff0c;“馏分燃料”等共9个指标的数据&#xff08;其中早期的部分…

yarn/npm certificate has expired

目录 报错 原因&#xff1a;HTTPS 证书验证失败 方法 a.检查网络安全软件&#xff1a;可能会拦截或修改 HTTPS 流量 b.strict-ssl:false关闭验证【临时方法】 报错 info No lockfile found. [1/4] Resolving packages... error Error: certificate has expired at TLS…

【华三】GRE VPN 实验配置

【华三】GRE VPN 实验配置 前言报文格式实验需求配置思路配置拓扑GRE配置步骤R1基础配置GRE 配置ISP_R2基础配置R3基础配置GRE 配置PCPC1PC2抓包检查OSPF建立GRE隧道建立配置文档前言 VPN :(Virtual Private Network),即“虚拟专用网络”。 它是一种通过公用网络(通常是互…

骨传导耳机是什么原理?适合什么场景使用?

骨传导耳机是一种非常特殊的蓝牙耳机&#xff0c;它们通过骨传导技术将声音直接传送到内耳。这种技术不同于传统耳机&#xff0c;它不通过空气传送声音&#xff0c;而是通过头骨的振动来传送声音。 骨传导耳机的传声原理跟传统耳机有所不同&#xff0c;传统耳机通过空气振动将…

爱上算法:每日算法(24-2月2号)

&#x1f31f;坚持每日刷算法&#xff0c;将其变为习惯&#x1f91b; 题目链接&#xff1a;101. 对称二叉树 最开始肯定是比较简单的想法&#xff0c;就是遍历左右节点呀&#xff0c;不相等我就直接返回false。 但是这样错了&#xff0c;我们要的是以根节点为轴&#xff0c;而…

使用 Python、Elasticsearch 和 Kibana 分析波士顿凯尔特人队

作者&#xff1a;来自 Jessica Garson 大约一年前&#xff0c;我经历了一段压力很大的时期&#xff0c;最后参加了一场篮球比赛。 在整个过程中&#xff0c;我可以以一种我以前无法做到的方式断开连接并找到焦点。 我加入的第一支球队是波士顿凯尔特人队。 波士顿凯尔特人队是…

【Linux】文件周边002之初步理解文件管理(打开的文件)

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 1.&#xff08;打开…

PMP资料怎么学?PMP备考经验分享

PMP考试前大家大多都是提前备考个一两个月&#xff0c;但是有些朋友喜欢“不走寻常路”&#xff0c;并不打算去考PMP认证&#xff0c;想要单纯了解PMP&#xff0c;不管要不要考证&#xff0c;即使是仅仅学习了解一下我个人都非常支持&#xff0c;因为专业的基础的确能提高工作效…

【Linux系统 02】Shell脚本

目录 一、Shell概述 二、输入输出 三、分支控制 1. 表达式 2. if 分支 3. case 分支 四、循环控制 1. for 循环 2. while 循环 3. select 循环 五、函数 一、Shell概述 Shell是Linux系统连接用户和操作系统的外壳程序&#xff0c;将用户的输入和请求选择性传递给操…

Unity笔记:相机移动

基础知识 鼠标输入 在Unity中&#xff0c;开发者在“Edit” > “Project Settings” > “Input Manager”中设置输入&#xff0c;如下图所示&#xff1a; 在设置了Mouse X后&#xff0c;Input.GetAxis("Mouse X")返回的是鼠标在X轴上的增量值。这意味着它会…

考勤|基于Springboot的大学生考勤系统设计与实现(源码+数据库+文档)

大学生考勤系统目录 目录 基于Springboot的大学生考勤系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、系统登录注册 2、管理员功能模块 3、教师功能模块 4、学生功能模块 四、数据库设计 1、实体ER图 2、具体的表设计如下所示&#xff1a; 五、核心代码…

【CSS + ElementUI】更改 el-carousel 指示器样式且隐藏左右箭头

需求 前三条数据以走马灯形式展现&#xff0c;指示器 hover 时可以切换到对应内容 实现 <template><div v-loading"latestLoading"><div class"upload-first" v-show"latestThreeList.length > 0"><el-carousel ind…

@所有人 您需要的 幻兽帕鲁服务器搭建教程 已上线

所有人 您需要的 幻兽帕鲁服务器搭建教程 已上线 幻兽帕鲁一键购买及部署体验购买及部署购买云服务器ECS部署幻兽帕鲁 创建账户并登录Steam其他操作更新服务器修改游戏参数其他操作释放资源 一直拖到今天才来写这篇幻兽帕鲁服务器搭建教程&#xff0c;确实是因为前段时间有事耽…

【Rust】——rust前言与安装rust

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…

机器学习系列5-特征组合、简化正则化

1.特征组合 1.1特征组合&#xff1a;编码非线性规律 我们做出如下假设&#xff1a;蓝点代表生病的树。橙色的点代表健康的树。 您可以绘制一条直线将生病的树与健康的树清晰地分开吗&#xff1f;不可以。这是一个非线性问题。您绘制的任何线条都无法很好地预测树的健康状况…

R语言学习case12:ggplot 置信区间(多线型)

接上文&#xff1a;多条曲线 R语言学习case11&#xff1a;ggplot 置信区间&#xff08;包含多子图&#xff09; 在ggplot2中&#xff0c;每个geom函数都接受一个映射参数。然而&#xff0c;并非每个美学属性都适用于每个geom。你可以设置点的形状&#xff0c;但不能设置线的“…

群晖NAS开启FTP服务结合内网穿透实现公网远程访问本地服务

⛳️ 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 文章目录 ⛳️ 推荐1. 群晖安装Cpolar2. 创建FTP公网地址3. 开启群晖FTP服务4. 群晖FTP远程连接5. 固定FTP公网地址6. 固定FTP…

产品经理学习-产品运营《如何策划一场活动》

互联网活动怎么玩 最常听到的有&#xff1a; 注册有奖、拉新有奖 签到积分 秒杀、大促、神券 和过去相比&#xff0c;现在活动的特征变化&#xff1a; 线上化、形式丰富、覆盖人群广、即时性、效果可控 什么是活动运营 通过策划不同形式的活动&#xff0c;进行有效的资源和…

LFU缓存(Leetcode460)

例题&#xff1a; 分析&#xff1a; 这道题可以用两个哈希表来实现&#xff0c;一个hash表&#xff08;kvMap&#xff09;用来存储节点&#xff0c;另一个hash表&#xff08;freqMap&#xff09;用来存储双向链表&#xff0c;链表的头节点代表最近使用的元素&#xff0c;离头节…

SpringBoot注解--02---常用注解汇总

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.SpringBoot 配置启动注解SpringBootApplication 2.Bean处理注解2.1 依赖注入AutoWired、Qualifier、Resource 2.2 类被 Spring 容器创建&#xff0c;管理 iocComp…