定义函数对象

C语言隐式/显式类型转换 | C++四种强制类型转换、类的隐式转换、explicit 文章目录何时发生隐式类型转换 何时发生隐式类型转换 在大多数表达式中,比int类型小的整数值提升为较大的整数类型 在条件中,非布尔值转换成布尔类型 初始化过程中,初始值转换成变量的类型;在赋值语句中,右侧运算对象转化成左侧运算对象的类型 算术运算或关系运算对象有多种类型,需要转换成同一种类型 函数调用时也会发生类型转换 ... 阅读详情
尽管函数指针被广泛用于实现函数回调,但C++还提供了一个重要的实现回调函数的方法,那就是函数对象。函数对象(也称“算符”)是重载了“()”操作符的普通类对象。因此从语法上讲,函数对象与普通的函数行为类似。

用函数对象代替函数指针有几个优点,首先,因为对象可以在内部修改而不用改动外部接口,因此设计更灵活,更富有弹性。函数对象也具备有存储先前调用结果的数据成员。在使用普通函数时需要将先前调用的结果存储在全程或者本地静态变量中,但是全程或者本地静态变量有某些我们不愿意看到的缺陷。

其次,在函数对象中编译器能实现内联调用,从而更进一步增强了性能。这在函数指针中几乎是不可能实现的。

下面举例说明如何定义和使用函数对象。首先,声明一个普通的类并重载“()”操作符:

class Negate

{

public:

int operator() (int n) { return -n;}

};

重载操作语句中,记住第一个圆括弧总是空的,因为它代表重载的操作符名;第二个圆括弧是参数列表。一般在重载操作符时,参数数量是固定的,而重载“()”操作符时有所不同,它可以有任意多个参数。

因为在Negate中内建的操作是一元的(只有一个操作数),重载的“()”操作符也只有一个参数。返回类型与参数类型相同-本例中为int。函数返回与参数符号相反的整数。

使用函数对象

我们现在定义一个叫Callback()的函数来测试函数对象。Callback()有两个参数:一个为int一个是对类Negate的引用。Callback()将函数对象neg作为一个普通的函数名:

#include

using std::cout;

void Callback(int n, Negate & neg)

{

int val = neg(n); //调用重载的操作符“()”

cout << val;

}

不要的代码中,注意neg是对象,而不是函数。编译器将语句

int val = neg(n);

转化为

int val = neg.operator()(n);

通常,函数对象不定义构造函数和析构函数。因此,在创建和销毁过程中就不会发生任何问题。前面曾提到过,编译器能内联重载的操作符代码,所以就避免了与函数调用相关的运行时问题。

为了完成上面个例子,我们用主函数main()实现Callback()的参数传递:

int main()

{

Callback(5, Negate() ); //输出 -5

}

本例传递整数5和一个临时Negate对象到Callback(),然后程序输出-5。

模板函数对象

从上面的例子中可以看出,其数据类型被限制在int,而通用性是函数对象的优势之一,如何创建具有通用性的函数对象呢?方法是使用模板,也就是将重载的操作符“()”定义为类成员模板,以便函数对象适用于任何数据类型:如double,_int64或char:

class GenericNegate

{

public:

template T operator() (T t) const {return -t;}

};

int main()

{

GenericNegate negate;

cout<< negate(5.3333); // double

cout<< negate(10000000000i64); // __int64

}

如果用普通的回调函数实现上述的灵活性是相当困难的。

标准库中函数对象

C++标准库定义了几个有用的函数对象,它们可以被放到STL算法中。例如,sort()算法以判断对象(predicate object)作为其第三个参数。判断对象是一个返回Boolean型结果的模板化的函数对象。可以向sort()传递greater<>或者less<>来强行实现排序的升序或降序:

#include // for greater<> and less<>

#include //for sort()

#include

using namespace std;

int main()

{

vector vi;

//..填充向量

sort(vi.begin(), vi.end(), greater () );//降序( descending )

sort(vi.begin(), vi.end(), less () ); //升序 ( ascending )

}

 


5分钟搞定:用Ollama在MacBook上本地运行Qwen3大模型(附避坑指南) 本文详细介绍了如何在MacBook上使用Ollama快速部署和运行Qwen3大模型,包括安装步骤、性能优化技巧及常见问题解决方案。Ollama作为一款轻量级工具,特别适合M系列芯片的Mac用户,支持多种量化版本,显著降低资源消耗,提升推理速度。 阅读详情

相关推荐

告别OLE!Delphi操作Excel的3种轻量级方案横向评测(FlexCel/XLSReadWriteII/LibXL)

本文深入评测了Delphi操作Excel的三种轻量级方案:FlexCel、XLSReadWriteII和LibXL。通过技术架构、API设计、性能测试和实战案例的全面对比,帮助开发者选择最适合的工具,提升Excel文件处理效率,告别传统OLE方案的依赖和性能问题。

onion的博客 929

C++隐式类型转换

隐式类型转换针对不同的类型有不同的转换方式,总体可以分为两种类型,算术类型和类类型。 1. 算术类型转换 算术类型转换的设计原则就是尽可能避免损失精度。 具体地,有以下几条参考规则: 整型提升:将小整数类型转换成较大的整数类型。例如,如果一个运算对象的类型是long double,那么另外一个运算对象,无论它的类型是什么,都会被转换成long double。 有符号类型转换为无符号类型。类型转换一般不会改变对象内存的值,当一个有符号类型的对象转换为无符号类型时,其表示出来的值可能发生变化,例如,int a

M2嵌入式 7977

Mathtype公式排版避坑指南:固定行距20磅下如何完美显示上下标(实测有效)

本文针对学术论文在固定行距20磅要求下,Mathtype公式上下标显示不全或被裁剪的问题,提供了实测有效的解决方案。文章深入剖析了固定行距与公式排版的冲突原理,并详细指导用户通过调整Mathtype的“定义间距”参数(如下标深度、上标高度),以及利用“格式化公式”功能进行批量处理,确保公式在严格遵守期刊格式要求的同时清晰完整显示。

weixin_29228203的博客 1069

c++隐式类型转换和explicit

什么是隐式转换? 众所周知,C++的基本类型中并非完全的对立,部分数据类型之间是可以进行隐式转换的。 所谓隐式转换,是指不需要用户干预,编译器私下进行的类型转换行为。很多时候用户可能都不知道进行了哪些转换。 为什么要进行隐式转换? C++面向对象的多态特性,就是通过父类的类型实现对子类的封装。 通过隐式转换,你可以直接将一个子类的对象使用父类的类型进行返回。 在比如,数值和布尔类型的转...

weixin_30632089的博客 343

《哥谭神话-工程篇》02.Palantir的Ontology层(语义层) -企业操作系统的大脑

Ontology(语义层) 是Foundry 的核心层。Ontology 位于集成到 Foundry 中的数字资产(数据集和模型)之上,并将其连接到现实世界的对应物,从工厂、设备和产品等物理资产到客户订单或金融交易等概念。本篇将详细拆解Ontology(语义层)。

885

2021-8-14 EDK II编译

2021-8-14 EDK II 编译为什么要写这篇文章新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 为什么要写这篇文章 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdo

qq_45775660的博客 2946

C++中如何定义函数对象

C++中如何定义函数对象 尽管函数指针被广泛用于实现函数回调,但C++还提供了一个重要的实现回调函数的方法,那就是函数对象。函数对象(也称“算符”)是重载了“()”操作符的普通类对象。因此从语法上讲,函数对象与普通的函数行为类似。 用函数对象代替函数指针有几个优点,首先,因为对象可以在内部修改而不用改动外部接口,因此设计更灵活,更富有弹性。函数对象也具备有存储先前调用结果的数据成员。在使用普通函...

Poo_Chai的博客 1706

糖果【贪心】

【问题描述】 有N(1≤N <100,000)N(1≤N~<100,000)N(1≤N <100,000)种不同类型的糖果,每种糖果数量无限多。第i种糖果每颗的价格是Pi(1≤Pi≤1018),有Ci(1≤Ci≤1018)P_i(1≤P_i≤10^{18}),有C_i (1≤C_i≤10^{18)}Pi​(1≤Pi​≤1018),有Ci​(1≤Ci​≤1018)头牛想吃这种糖果。 FarmerJohnFarmer JohnFarmerJohn拥有金钱BBB元(1≤B≤1

算法小猪的博客 795

JS函数定义以及对象定义

1.JS中的函数定义,最好是用lambda方式创建,首先是方便,其次Vue中也用该方法创建函数/*函数表达式*/// 1.使用function关键字,add即为函数名return a+b;add(1+2);// 2.使用var定义函数,show即为函数名show(1001,"张三")// 3.定义多个函数var crud={console.log("新增");},console.log("查询");},},console.log("删除");

qq_58653738的博客 280

使用PlotNeuralNet绘制深度学习网络图的基本操作

使用PlotNeuralNet绘制深度学习网络图的基本操作

weixin_46877907的博客 2110

2026年3月GESP真题及题解(C++七级):物流网络

2026年3月GESP真题及题解(C++七级):物流网络

王老师青少年编程 1124

java 主函数里面定义对象

给大家整理了一些有关【Java,函数】的项目学习资料(附讲解~~):https://edu.51cto.com/course/35714.htmlhttps://edu.51cto.com/course/35079.html在 Java 主函数中定义对象 Java 是一种面向对象的编程语言,它通过类(class)和对象...

weixin_33279929的博客 203

【异常】OpenClaw网关仪表盘 pairing required 报错排查与解决方案

在OpenClaw网关仪表盘页面,完成WebSocket URL、网关令牌等必填项配置后,点击「连接」按钮尝试建立网关连接时,页面下方出现红色报错提示框,核心报错内容为,无法完成网关连接建立,且该报错在令牌配置正确、网络链路通畅的场景下仍会触发。该报错常见于非本地回环地址的访问场景,包括局域网远程访问、公网域名/IP访问、云服务器部署的网关远程管理等场景,本地127.0.0.1回环地址访问通常可正常连接。

奶爸的编程之路,也就一周冷个三天 1078

关于JavaScript中函数的定义、对象以及对象实例化的理解

趁近段时间不是很忙,把之前有关JS学习的一些笔记整理了一下: 函数的定义:通俗点来讲,函数是由事件驱动或者它被调用时执行的可重复使用的代码块。在JS中,函数的定义方式通常有以下几种: (1)function语句(函数声明): 语法:function函数名(参数1,参数2…){函数体} 例:function test(a,b){ return(a+b); } (2)函数表达式,又称函数字面量: 语法:var 变量名=function(参数1,参数2…){函数体} 例:v

lianglizhongblog 3567

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

【C++】STL 算法 ⑧ ( 预定义函数对象 | 预定义函数对象组成 | 预定义函数对象分类 | 预定义 算术运算符 函数对象 | 预定义 比较运算符 函数对象 | 预定义 逻辑运算符 函数对象 )

一、预定义函数对象 1、预定义函数对象概念 2、预定义函数对象组成 二、预定义函数对象分类 1、预定义 算术运算符 函数对象 2、预定义 比较运算符 函数对象 3、预定义 逻辑运算符 函数对象 三、代码示例 - plus 函数对象使用 1、plus 函数对象 2、代码示例 3、执行结果

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 1560

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

js函数定义,js对象

js函数定义三种方式: 函数声明: function test(val) { console.log(val + "--->函数方式一"); }; 函数表达式: var f = new function(val) { alert("aaa"); console.log("ta---->函数方式二");

qq383264679的专栏 885

STL_函数对象、谓词、预定义函数对象、函数适配器

一、函数对象 重载函数调用操作符的类,其对象常称为函数对象(function object),即它们是行为类似函数的对象,也叫仿函数(functor),其实就是重载“()”操作符,使得类对象可以像函数那样调用。 注意: 函数对象(仿函数)是一个类,不是一个函数。 函数对象(仿函数)重载了”() ”操作符使得它可以像函数一样调用。 分类:假定某个类有一个重载的operator(),而且重载的operator()要求获取一个参数,我们就将这个类称为“一元仿函数”(unary functor);相反,如果重载

季风的博客 295

C++中自己定义函数对象

创建函数对象   除了使用内置的函数对象外,我们还可以创建自己的函数对象,为了达到这个目的,只需要创建一个重载operator()函数的对象。然而,为了获得最大的灵活性,你会希望使用下面的这些类中的一个,这些类被STL定义为你所创建的函数对象的基类。template struct unary_function{ typedef Argument argument_typ

鹏程万里--扬帆起航 2321

STL函数对象之自定义函数对象

如何定义自己的函数对象,它使用于任何的绑定器 要定义自己的绑定器要满足一定的条件:必须提供参数和返回值的类型。 STL为我们提供了两个结构体: template struct unary_function { typedef Arg argument_type; typedef Result result_type; }; template struct binary_fun

FlowShell的专栏 1075

对象作为函数参数、类外定义成员函数

一、对象作为函数的参数 对象也可以作为函数的参数传递给函数,其转递方法与传递其他类型的数据一样,可采用值传递和地址传递两种方法。 值传递时是把对象的拷贝而不是本身传递给函数,函数中对参数对象的任何修改都不会影响调用该函数的对象本身; 而地址传递时,调用该函数的对象与参数对象共用同一个地址,所以,函数对参数对象的任何修改都会影响调用该函数的对象本身。 #include<i...

224

函数对象与普通函数有什么区别? 如何定义和使用函数对象?

在这个例子中,MyFunctor()创建了一个临时的函数对象实例,并将其作为参数传递给std::for_each算法。总的来说,函数对象在C++中提供了一种灵活且强大的方式来封装和传递可调用行为,它们比普通函数更具封装性和状态管理能力。在这个例子中,MyFunctor是一个函数对象类型,它重载了operator()以接受一个int类型的参数。函数对象与普通函数在C++中有几个关键的区别,主要体现在它们的定义、使用场景以及灵活性上。使用函数对象时,首先需要创建该类型的实例,然后像调用函数一样调用该实例。

m0_74343664的博客 463
上一篇: 社交中要注意的事项
下一篇: 1的数目
General1982
博客等级 码龄19年 14粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值