当前位置:首页 > > 嵌入式微处理器
[导读]在我们日常编码中会发现有些功能代码,会不断的在不同的成员函数中用到,但是又不好将这些代码独立成一个成员函数。解决办法之一就是写一个公共的函数,不过函数用到的一些变量,就可能会成为全局变量。再说为了复用这么一段代码,就要单立出一个函数,也不是很好维护。此时就可以用到仿函数了。

【导读】:在我们日常编码中会发现有些功能代码,会不断的在不同的成员函数中用到,但是又不好将这些代码独立成一个成员函数。解决办法之一就是写一个公共的函数,不过函数用到的一些变量,就可能会成为全局变量。再说为了复用这么一段代码,就要单立出一个函数,也不是很好维护。此时就可以用到仿函数了。


以下是正文



引入仿函数(functor)原因


先考虑一个简单的例子:假设有一个vector,你的任务是统计长度小于5的string的个数,如果使用count_if函数的话,你的代码可能长成这样:

bool LengthIsLessThanFive(const string& str){    return str.length() < 5;    }int res=count_if(vec.begin(), vec.end(), LengthIsLessThanFive);

其中count_if函数的第三个参数是一个函数指针,返回一个bool类型的值。一般的,如果需要将特定的阈值长度也传入的话,我们可能将函数写成这样:

bool LenthIsLessThan(const string& str, int len) {    return str.length() < len;}

这个函数看起来比前面一个版本更具有一般性,但是他不能满足count_if函数的参数要求:count_if要求的是unary function(仅带有一个参数)作为它的最后一个参数。所以问题来了,怎么样找到以上两个函数的一个折中的解决方案呢?


这个问题其实可以归结于一个data flow的问题,要设计这样一个函数,使其能够access这个特定的length值,回顾我们已有的知识,有三种解决方案可以考虑:


(1)函数的局部变量:

局部变量不能在函数调用中传递,而且caller无法访问。


(2)函数的参数:

这种方法我们已经讨论过了,多个参数不适用于count_if函数。


(3)全局变量:

我们可以将长度阈值设置成一个全局变量,代码可能像这样:

int maxLength;bool LengthIsLessThan(const string& str) { return str.length() < maxLength;}int res=count_if(vec.begiin(), vec.end(), LengthIsLessThan);

这段代码看似很不错,实则不符合规范,更重要的是,它不优雅。原因有以下几点要考虑:


(1)容易出错:

为什么这么说呢,我们必须先初始化maxLength的值,才能继续接下来的工作,如果我们忘了,则可能无法得到正确答案。此外,变量maxLength和函数LengthIsLessThan之间是没有必然联系的,编译器无法确定在调用该函数前是否将变量初始化,给码农平添负担。


(2)没有可扩展性:

如果我们每遇到一个类似的问题就新建一个全局变量,尤其是多人合作写代码时,很容易引起命名空间污染(namespace polution)的问题;当范围域内有多个变量时,我们用到的可能不是我们想要的那个。


(3)全局变量的问题:

每当新建一个全局变量,即使是为了coding的便利,我们也要知道我们应该尽可能的少使用全局变量,因为它的cost很高;而且可能暗示你这里有一些待解决的优化方案。


仿函数(functor)介绍


说了这么多,还是要回到我们原始的那个问题,有什么解决方案呢?答案当然就是这篇blog的正题部分:仿函数。


我们的初衷是想设计一个unary function,使其能做binary function的工作,这看起来并不容易,但是仿函数能解决这个问题。


先来看仿函数的通俗定义:仿函数(functor)又称为函数对象(function object)是一个能行使函数功能的类。仿函数的语法几乎和我们普通的函数调用一样,不过作为仿函数的类,都必须重载operator()运算符,举个例子:

class Func{ public: void operator() (const string& str) const { cout<endl;        }};Func myFunc;myFunc("helloworld!");

>>>helloworld!


仿函数其实是上述解决方案中的第四种方案:成员变量。成员函数可以很自然的访问成员变量:

class StringAppend{ public: explicit StringAppend(const string& str) : ss(str){}
void operator() (const string& str) const{ cout<' '< }
private: const string ss; };
StringAppend myFunc("is world"); myFunc("hello");

>>>hellois world


我相信这个例子能让你体会到一点点仿函数的作用了;它既能像普通函数一样传入给定数量的参数,还能存储或者处理更多我们需要的有用信息。


让我们回到count_if的问题中去,是不是觉得问题变得豁然开朗了?

class ShorterThan { public: explicit ShorterThan(int maxLength) : length(maxLength) {} bool operator() (const string& str) const  { return str.length() < length; } private: const int length;};//直接调用即可count_if(myVector.begin(), myVector.end(), ShorterThan(length));

这里需要注意的是,不要纠结于语法问题:ShorterThan(length)似乎并没有调用operator()函数?其实它调用了,创建了一个临时对象。你也可以自己加一些输出语句看一看。


这篇博文就先记到这里了,仿函数也在STL中大量涉及到,不彻底弄懂仿函数的问题看到STL源码就会一头包。后续可能再分享一些关于functor的资料和个人学习心得。


-END-


来源 | dnbc66

www.cnblogs.com/decade-dnbc66/p/5347088.html


整理文章为传播相关技术,版权归原作者所有 |

如有侵权,请联系删除 |


【1】嵌入式研发10多年,工程师悟出这些道理

【2】当谈起嵌入式工程师,究竟在谈些什么

【3】嵌入式工程师出路之我见:就业,技术,行业...

【4】为什么嵌入式工程师会对8位MCU有误解?

【5】嵌入式工程师结合经历聊硬件工程师和软件工程师哪个更有前途?


免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

嵌入式ARM

扫描二维码,关注更多精彩内容

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

深圳2026年3月19日 /美通社/ -- 2026年的招聘市场,正陷入一场奇特的"算法互博":求职者用AI美化简历以通过筛选,企业用AI深挖细节以识别真伪。这场博弈的背后,是简历日益"丰满...

关键字: AI 代码 LAB 模型

当地时间 2 月 23 日,美股市场上演 AI 技术颠覆传统产业的剧烈一幕:人工智能公司 Anthropic 宣布旗下 Claude Code 产品新增 COBOL 编程语言现代化处理能力后,国际商业机器公司(IBM)股...

关键字: IBM Anthropic AI 编程

美国旧金山和中国苏州2026年2月8日 /美通社/ -- 信达生物制药集团(香港联交所股票代码:01801),一家致力于研发、生产和销售肿瘤、自身免疫、代谢、眼科等重大疾病领域创新药物的生物制药公司,宣布与礼来制药达成战...

关键字: COM 代码 创始人 控制

香港2026年2月4日 /美通社/ -- 华钦科技集团(纳斯达克代码:CLPS,以下简称"华钦科技"或"集团")今日宣布其董事会已通过一项集团股份回购计划的决议。该决议声明,当集团股价低于每股2美元时,集团可在公开市场上...

关键字: PS BSP 代码 纳斯达克

-Basecamp Research推出全球首个可编程基因插入AI模型 此突破可解决遗传医学长期存在的挑战,目标是开发新一代治愈性细胞和基因疗法。 与NVIDIA合作开发,依靠NVIDIA BioNeMo的加...

关键字: 编程 SE AI模型 RESEARCH

在C语言编程中,循环结构是处理重复任务的核心工具,而break和continue则是控制循环流程的关键指令。虽然两者都用于改变循环的正常执行路径,但它们的行为和适用场景存在本质差异。

关键字: C语言 编程

香港2025年12月11日 /美通社/ -- 诺亚控股有限公司(Noah Holdings Limited,以下简称"诺亚"或"公司",纽交所代码:NOAH,港交所代码:6686)...

关键字: AI 代码 AN 操作系统

弗吉尼亚州阿什本2025年12月10日 /美通社/ -- 企业技术与创新领域的领先合作伙伴DXC Technology(纽约证券交易所代码:DXC)今日宣布推出AdvisoryX,这是一支旨在帮助企业应对最复杂的战略、运...

关键字: ADVISOR AI TECHNOLOGY 代码

新加坡2025年12月8日 /美通社/ -- 近日,51Talk在线教育集团("51Talk"或"公司")(纽约证券交易所美国股票代码:COE)公布了其截至2025年9月...

关键字: BSP 代码 创始人 新加坡

济南2025年12月2日 /美通社/ -- 2025年11月30日,第三届山东省青少年无人机大赛泰安区域选拔赛在浪潮探索中心泰安科创教育基地举行。泰安市科协、泰山区科协、山东省无人机技术与应用协会、山东浪潮盛华智慧教育有...

关键字: 大赛 无人机 人工智能 编程
关闭