生活工程体验信仰哲学精神
投稿投诉
精神世界
探索历史
哲学文学
艺术价值
信仰创造
境界审美
体验技术
技能工具
工程信息
医学生产
生活运用
操作能力

C辨析函数指针函数对象Lambda表达式及后者最优的原因

9月13日 终不悔投稿
  试想有一排序函数sort(intarr〔〕)默认为升序排序,如果想更改为降序排列,最直接的方法就是在函数体中修改比较运算符,但这种修改函数体的方法不够灵活,特别是如果sort(intarr〔〕)要封装到库(接口与实现分离)时,库使用者是无法去修改函数体的。理想的方法是修改接口,在接口在添加一函数指针做为形式参数,在函数体中调用函数指针,这样,函数体中的代码就可以固定下来,而选择升序还是降序排列,则由函数指针指向的函数来决定。
  函数指针、函数对象、Lambda表达式都可以实现同样的功能:structFuncObj{constexprFuncObj()intoperator()(inta){returnrun(a);}thisisanoncapturinglambda,theoperatorcanbeinastaticfunctionstaticintrun(inta){}};typedefint(funcp)(inta);templatefuncpfoointfunc(inta)intfunc(inta,funcpfoo){foo(a);}intfunc(inta,FuncObjlt){lt(a);}intfuncpRelated(inta){}intmain(){autolambda〔〕(inta){};类型相同,不能捕捉coutfunc(23,funcpRelated)coutfunc(24,lambda)FuncOcoutfunc(25,obj)functionint(int)fintobjFuncObj();coutfintobj(26)functionFuncObj::run(1);thisisworkingreturn0;}
  函数指针、函数对象、Lambda表达式对STL算法的使用:includeiostreamincludevectorincludeincludecmathincludectimeconstlongSize139L;constlongSize2100Size1;constlongSize3100Size2;boolf3(intx){returnx30;}boolf13(intx){returnx130;}intmain(){usingstd::std::vectorintnumbers(Size1);std::srand(std::time(0));std::generate(numbers。begin(),numbers。end(),std::rand);usingfunctionpointerscoutSamplesizeSize1;intcount3std::countif(numbers。begin(),numbers。end(),f3);coutCountofnumberspisibleby3:count3;intcount13std::countif(numbers。begin(),numbers。end(),f13);coutCountofnumberspisibleby13:count13;increasenumberofnumbersnumbers。resize(Size2);std::generate(numbers。begin(),numbers。end(),std::rand);coutSamplesizeSize2;usingafunctorclassfmod{private:public:fmod(intd1):dv(d){}booloperator()(intx){returnxdv0;}};count3std::countif(numbers。begin(),numbers。end(),fmod(3));coutCountofnumberspisibleby3:count3;count13std::countif(numbers。begin(),numbers。end(),fmod(13));coutCountofnumberspisibleby13:count13;increasenumberofnumbersagainnumbers。resize(Size3);std::generate(numbers。begin(),numbers。end(),std::rand);coutSamplesizeSize3;usinglambdascount3std::countif(numbers。begin(),numbers。end(),〔〕(intx){returnx30;});coutCountofnumberspisibleby3:count3;count13std::countif(numbers。begin(),numbers。end(),〔〕(intx){returnx130;});coutCountofnumberspisibleby13:count13;std::cin。get();return0;}
  输出:Samplesize39Countofnumberspisibleby3:14Countofnumberspisibleby13:0Samplesize3900Countofnumberspisibleby3:1365Countofnumberspisibleby13:289Samplesize390000Countofnumberspisibleby3:129968Countofnumberspisibleby13:30393
  函数数指针、函数对象、Lambda表达式的使用,可以从以下几个方面来区别:
  1距离:让定义位于使用的地方最近是一种最佳的选择。这是Lambda表达式的优势。函数对象是次优的选择,因为函数对象的类也可以定义在函数内部。最差的是函数指针了,距离最远。
  2简洁:是指代码的简洁度。Lambda表达式的代码最简洁,函数指针次之,函数对象虽然相对于函数指针来说,可以实现状态数据的存储,但代码的简洁度最差。
  3效率
  这三种方法的相对效率取决于编译器内联那些东西。函数指针方法阻止了内联(能够内联的代码,执行效率比较高),因为编译器传统上不会内联其地址被获取的函数,因为函数地址的概念意味着非内联函数。而函数对象和lambda通常不会阻止内联。
  4功能
  lambda有一些额外的功能。具体地说,lambad可访问作用域内的任何动态变量;要捕获要使用的变量,可将其名称放在中括号内。如果只指定了变量名,如〔z〕,将按值访问变量;如果在名称前加上,如〔count〕,将按引用访问变量。〔〕让您能够按引用访问所有动态变量,而〔〕让您能够按值访问所有动态变量。还可混合使用这两种方式,例如〔ted,ed〕让您能够按值访问ted以及按引用访问ed,〔,ted〕让您能够按值访问ted以及按引用访问其他所有动态变量,,ed让您能够按引用访问ed以及按值访问其他所有动态变量。
  看下面的实例:lambda1。cppusecapturedvariablesincludeiostreamincludevectorincludeincludecmathincludectimeconstlongSize390000L;intmain(){usingstd::std::vectorintnumbers(Size);std::srand(std::time(0));std::generate(numbers。begin(),numbers。end(),std::rand);coutSamplesizeSusinglambdasintcount3std::countif(numbers。begin(),numbers。end(),〔〕(intx){returnx30;});coutCountofnumberspisibleby3:count3;intcount130;std::foreach(numbers。begin(),numbers。end(),〔count13〕(intx){count13x130;});coutCountofnumberspisibleby13:count13;usingasinglelambdacount3count130;std::foreach(numbers。begin(),numbers。end(),〔〕(intx){count3x30;count13x130;});coutCountofnumberspisibleby3:count3;coutCountofnumberspisibleby13:count13;std::cin。get();return0;}
  输出:Samplesize390000Countofnumberspisibleby3:130144Countofnumberspisibleby13:29939Countofnumberspisibleby3:130144Countofnumberspisibleby13:29939
  用表格综合一下以上4项区别:
  表格数据:
  函数指针
  函数对象
  lambda表达式
  距离
  定位位置与使用位置
  最差
  次优
  最优
  简洁
  代码的简洁度
  次优
  最差
  最优
  效率
  可内联的代码效率要高
  不能内联
  可内联
  可内联
  功能
  额外功能
  可访问作用域内的任何动态变量
  ref
  StephenPrata:《CPrimerPlus(6th2011)》
  End
投诉 评论 转载

德媒速译从阿富汗成功逃往欧洲的女性有多难《明镜》周刊No。332021。8。14文章,原题:沉默的女英雄们内容提要:难民政策:从阿富汗成功逃往德国难民的主要是男性。独自逃离的女性必须在这个国家抗争。……蜜雪冰城开始卖咖啡了?五元一杯?虽说最近蜜雪冰城MV主题曲的热度有些下降的趋势但是只要晃晃脑袋,还是能回响起那句你爱我,我爱你,蜜雪冰城甜蜜蜜的魔性歌词可就当小编还在赞叹蜜……2991亿元!中国石化品牌价值蝉联能源化工行业第一中国石化品牌价值高达2991亿元,在全国排名第二,仅次于中国工商银行。旗下业务品牌价值骤升,易捷品牌价值161亿元,易派客品牌价值98亿元,长城润滑油品牌价值77亿元,东海牌沥……不良资产处置业务发力摩恩电气业绩拐点出现8月23日,上海摩恩电气股份有限公司(摩恩电气)公布的2017半年度报告显示,公司上半年实现营业收入为2。05亿元,实现归属于上市公司股东的净利润为2137。70万元,同比增长……C辨析函数指针函数对象Lambda表达式及后者最优的原因试想有一排序函数sort(intarr〔〕)默认为升序排序,如果想更改为降序排列,最直接的方法就是在函数体中修改比较运算符,但这种修改函数体的方法不够灵活,特别是如果sort(……英国加入AUKUS组织,全国只有10个人知道中国的复兴,就像是海面上突然出现的鲸鱼,让很多国家不知所措,甚至大惊失色,其心理固然可以理解,但盲目举起鱼叉却殊为不智,这会引起毁灭性的后果。据《参考消息》9月21日的报道,就……NBA历史上最牛的六次绝杀1。麦迪35秒13分狙杀马刺。这可能是球迷们最津津乐道的一个绝杀吧,同时麦迪的35秒13分不仅将他的天赋尽显无疑,更在国内甚至全世界收获大片的球迷,让时光回到2004年1……第一部俄罗斯太空电影实验导演俄罗斯电影导演克里姆希彭科周一表示,在他进入太空之旅的前夜,轨道上的第一部电影将是一场实验,希望击败好莱坞的竞争对手。这位38岁的导演和俄罗斯最著名的女演员之一、37岁的……科创之星丨锐沣科技冯玉林3D打印掘金隐形正畸市场出品创新湾(ID:EnnoBay)作者蒙亦编辑夏至头图Pixabay创新湾导读:本期《科创之星》采访嘉宾由廊湾产业加速器推荐。隐形牙套是一个因3D打印而……2021年7月18日收到的异常报告含羞草闭合今天收到异常报告1条,来自云南大理。异常报告1、2021年7月18日下午15时42分收到云南大理网友汇报发现含羞草部分闭合的现象,并且反映当地布谷鸟早晨开始鸣叫并且反应5……日图科技即将亮相2020中国智能汽车技术大会(IMCA第十七届国际论坛2020中国智能汽车技术大会暨中国汽车质量与测试展将于2020年11月45日在广州南沙大酒店隆重举行。)关于日图科技深圳市日图科技有限公司……四年级数学巧记法总结点赞收藏两位数乘法法则整数乘法低位起,两位数乘法两次积。个位数乘得若干一,积的末位对个位。十位数乘得若干十,积的末位对十位。计算准确对好位,两次乘积加一起。……
防务动态国外一周防务要闻(2021。06。212021。06台风与女性的故事干货来袭!澳洲中国留学生最需要的签证详解两艘航母制霸亚太的时代过去了!中国冲破围堵,美国军舰却不够了38亿年后银河系和仙女座星系发生碰撞,人类该如何应对?超越中国被打脸,豪华高铁惨遭抛弃?印度接连遭受暴击阿富汗战争黯然落幕撤军带来巨大打击拜登面临卡特时刻海边的卡夫卡儿子醒来后,满身是血,他是否杀死了他父亲?明天的采矿工人将彻底失业,又一个将要没落的行业新书推荐纳米生物材料黄花梨圈椅赏析当这个谜团被解开的时候,可能就是人类延长寿命的时候了
美国如果印钞发给国民,算不算打劫全世界?棋坛惊现16岁天才惨遭十虎王炸弃车速杀,吕钦抖音解说神析因荣耀30怎么样荣耀30值不值得买如何开始第一场可用性测试窑洞宾馆(西安窑洞民宿)诸葛亮病死五丈原的历史原因是什么他真有司马懿想的关于电灯泡的青春往事蹲久了起立眼前发黑是心脏的问题吗?枣强华润面粉厂今日小麦价格中国下一个举办奥运会的城市最可能会是哪个?两个乞丐作文范文已经吃了21年降压药,还能活几年?长期吃降压药会减寿?药师详

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找新乡渭南铜川松江山南雅安松原荃湾淮北昭通平凉鞍山赤峰苗栗保亭池州渝北株洲陇南濮阳三沙秀山密云鸡西