C++11:function包装器

包装器,体现了C++11中的封装性,包装器可以应用于:函数指针,仿函数,lambda

而包装器function的出现刚好也弥补了上述三种语法的不足之处

函数指针写起来较为复杂,而仿函数之间类型不同,lambda则在语法层压根没有类型

而function的目的就是封装它们统一类型。

一、function包装器

function包装器 也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。
那么我们来看看,我们为什么需要function
//ret = func(x);
// 上面func可能是什么呢?那么func可能是函数名?函数指针?函数对象(仿函数对象)?也有可能
//是lamber表达式对象?所以这些都是可调用的类型!如此丰富的类型,可能会导致模板的效率低下!
template<class F, class T>
T useF(F f, T x)
{static int count = 0;cout << "count:" << ++count << endl;cout << "count:" << &count << endl;return f(x);
}
double f(double i)
{return i / 2;
}
struct Functor
{double operator()(double d){return d / 3;}
};
int main()
{// 函数名cout << useF(f, 11.11) << endl;// 函数对象cout << useF(Functor(), 11.11) << endl;// lamber表达式cout << useF([](double d)->double { return d / 4; }, 11.11) << endl;return 0;
}

这里的useF在编译时因为参数类型的不同会被实例化出三份,当多次调用传不同参数时就会被实例化出多份,而function包装器就可以很好的解决这个问题。天空一声巨响,可变模板参数包闪亮登场:

std::function在头文件<functional>
// 类模板原型如下
template <class T> function;     // undefined
template <class Ret, class... Args>
class function<Ret(Args...)>;
模板参数说明:
Ret: 被调用函数的返回类型
Args…:被调用函数的形参

基于function我们就可以对上面的代码进行改造:

template<class F, class T>
T useF(F f, T x)
{static int count = 0;cout << "count:" << ++count << endl;cout << "count:" << &count << endl;return f(x);
}
double f(double i)
{return i / 2;
}
struct Functor
{double operator()(double d){return d / 3;}
};
int main()
{// 函数指针function<double(double)> fc1=f;cout << useF(fc1, 11.11) << endl; // 函数对象function<double(double)> fc2 = Functor();cout << useF(fc2, 11.11) << endl;// lambda表达式function<double(double)> fc3 = [](double d)->double { return d / 4; };cout << useF(fc3, 11.11) << endl;return 0;
}

这时三个参数都是function<double(double)>类型的,而这时useF只需要实例化出一份就可以了。

 二、function实际应用

根据 逆波兰表示法,求该后缀表达式的计算结果。

有效的算符包括 +-*/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

  • 整数除法只保留整数部分。
  • 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

示例 1:

输入:tokens = ["2","1","+","3","*"]
输出:9
解释:该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

示例 2:

输入:tokens = ["4","13","5","/","+"]
输出:6
解释:该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

示例 3:

输入:tokens = ["10","6","9","3","+","-11","*","/","*","17","+","5","+"]
输出:22
解释:
该算式转化为常见的中缀算术表达式为:((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22

提示:

  • 1 <= tokens.length <= 104
  • tokens[i] 要么是一个算符("+""-""*" 或 "/"),要么是一个在范围 [-200, 200] 内的整数

逆波兰表达式:

逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。

  • 平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。
  • 该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。

逆波兰表达式主要有以下两个优点:

  • 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。
  • 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。
class Solution {
public:int evalRPN(vector<string>& tokens) {map<string,function<int(int,int)>> opFuncMap={{"+",[](int x,int y){return x+y;}},{"-",[](int x,int y){return x-y;}},{"*",[](int x,int y){return x*y;}},{"/",[](int x,int y){return x/y;}}};stack<int> st;for(auto& str :tokens){if(opFuncMap.count(str)){int right=st.top();st.pop();int left=st.top();st.pop();st.push(opFuncMap[str](left,right));}else//操作数入栈{st.push(stoi(str));}}return st.top();}
};

这里就可以通过function来对应不同的操作符进行包装从而将不同的lambda函数进行包装,然后和相对应的操作符放入map中。然后从头遍历字符串,如果是数字类的char就存入栈中,如果是操作符就将栈顶的两个数进行操作符所对应的运算,然后重新放入栈中,直到字符串遍历完栈内存放的数就是最后的结果。

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

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

相关文章

数学建模笔记(10)整数规划和0-1规划

前由 显然通关次数不能是小数&#xff0c;这就涉及到了整数问题。 定义 例题

最新mysql8.3 保姆级 主从复制搭建教程

mysql 主从复制搭建 服务器配置表 机器ip操作系统主机192.168.31.25华为openEuler-22.03-LTS-SP3从机192.168.31.184华为openEuler-22.03-LTS-SP3从机192.168.31.228华为openEuler-22.03-LTS-SP3 1、在3台机器上安装独立的 mysql 1.1 创建myql文件夹用来存放mysql包 mkdir…

python-可视化篇-turtle-画爱心

文章目录 原效果替换关键字5为8&#xff0c;看看效果改下颜色 原效果 import turtle as tt.color(red,pink) t.begin_fill() t.width(5) t.left(135) t.fd(100) t.right(180) t.circle(50,-180) t.left(90) t.circle(50,-180) t.right(180) t.fd(100) t.pu() t.goto(50,-30) t…

【用户案例】太美医疗基于Apache DolphinScheduler的应用实践

大家好&#xff0c;我叫杨佳豪&#xff0c;来自于太美医疗。今天我为大家分享的是Apache DolphinScheduler在太美医疗的应用实践。今天的分享主要分为四个部分&#xff1a; 使用历程及选择理由稳定性的改造功能定制与自动化部署运维巡检与优化 使用历程及选择理由 公司介绍 …

尝试在手机上运行google 最新开源的gpt模型 gemma

Gemma介绍 Gemma简介 Gemma是谷歌于2024年2月21日发布的一系列轻量级、最先进的开放语言模型&#xff0c;使用了与创建Gemini模型相同的研究和技术。由Google DeepMind和Google其他团队共同开发。 Gemma提供两种尺寸的模型权重&#xff1a;2B和7B。每种尺寸都带有经过预训练&a…

【iOS ARKit】AR Quick Look 概述

为更好地传播共享 AR 体验&#xff0c;苹果公司引入了 AR Quick Look&#xff0c;并在iOS 12及以上版本系统中深度集成了 AR Quick Look&#xff0c;因此可以通过iMessage、Mail、Notes、 News、 Safari 和 Files 直接体验 AR&#xff0c;AR Quick Look提供了在 iPhone 和iPad …

排序算法,插入排序

插入排序是什么 插入排序&#xff08;Insertion Sort&#xff09;&#xff0c;一般也被称为直接插入排序。对于少量元素的排序&#xff0c;它是一个有效、简单的算法 其主要的实现思想是将数据按照一定的顺序一个一个的插入到有序的表中&#xff0c;最终得到的序列就是已经排…

隐私计算实训营第九讲-隐语多方安全计算在安全核对的行业实践

隐私计算实训营第九讲-隐语多方安全计算在安全核对的行业实践 文章目录 隐私计算实训营第九讲-隐语多方安全计算在安全核对的行业实践1.业务背景&#xff1a;安全核对产生的土壤1.1相关政策出台1.2 数据差异的来源 2.产品方案&#xff1a;从试点到规模化的路3.技术共建&#xf…

如何用MATLAB进行核密度估计

核密度估计&#xff08;Kernel Density Estimation&#xff0c;KDE&#xff09;是一种用于估计概率密度函数的非参数方法。以下是核密度估计的基本步骤和公式&#xff1a; 步骤&#xff1a; (1)数据预处理&#xff1a;在进行核密度估计之前&#xff0c;需要对原始数据进行清洗…

微信小程序报错——“errno“: 600001, “errMsg“: “request:fail -2:net::ERR_FAILED“

bug现象 微信小程序体验版和真机调试 进入小程序的时候接口就出现了这个报错 "errno": 600001, "errMsg": "request:fail -2:net::ERR_FAILED" 排查 检查是证书过期还是证书链不完整 证书的信任链完整问题&#xff0c;可以在 亚数信息-SSL/TLS安…

web安全学习笔记(8)

记一下第十二节课的内容。 一、PHP文件包含的四种方式 Include和Include_once 操作系统会读取包含的文件的内容&#xff0c;并将它插入主文件中&#xff0c;include方式的文件包含会在包含失败的情况下输出警告信息&#xff0c;而include_once方式会检查包含的文件是否已经被…

Jmeter —— 自动录制脚本

1、Jmeter配置 1.1新增一个线程组 1.2Jmeter中添加HTTP代理 1.3配置HTTP代理服务器 修改端口 修改Target Cintroller(目标控制器) 修改Grouping(分组) 编辑录制中的包含和排除 在“URL Patterns to include包含模式”中填入.*(123456).*用以过滤请求地址中不包含123456的请求…

Datacom HCIP笔记-MPLS协议 之二

在Ingress节点执行该命令时&#xff0c;触发所有的32位路由建立LDPLSP。 在Egress节点执行该命令时&#xff0c;触发本地32位路由建立LDPLSP&#xff0c; egress就是主机路由始发路由器 ingress就是主机路由非始发路由器 默认情况下&#xff1a;华为路由器仅为非物理接口主机路…

【C++11】initializer_list | 右值引用 | 完美转发

一切皆可列表{ }初始化 在C98,允许花括号{ } 对数组、结构体类型初始化。 class Data { public:Data(int y, int m, int d):_y(y), _m(m), _d(d){} private:int _y;int _m;int _d; };int arr[4]{0,1,2,3};//列表初始化 Data d1{2024,03,21};//列表初始化 C11允许通过{ } 初始化…

云数据库价格一瞥(华为云、百度智能云、腾讯云、阿里云)

最近&#xff0c;大家似乎和价格“磕”上了。本文仅考虑主流产品&#xff08; RDS MySQL、Redis &#xff09;的部分主流规格&#xff0c;对各家厂商的价格做一个对比&#xff0c;供参考。 TL;DR&#xff1a; 总体来看&#xff0c;各家云厂商价格趋于持平&#xff0c;部分主流商…

创建一个qt登录界面,密码账号正确转到窗口2,否则弹出对话框提示账号密码错误,窗口2有四个按键,三个按键可以朗读按键文本,第四个退出。

作业要求&#xff1a; 主函数&#xff1a; int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();Form1 f;//连接窗口1的信号函数和窗口2打开的lambda函数Widget::connect(&w,&Widget::login,[&](){f.show();});return a.exec(); }窗…

无影云电脑不能连接到本机的调试串口的解决方案

目录 概述 解决方案 云端电脑中的操作 本地USBDK驱动程序的更新 概述 我从1月份开始使用阿里的无影云电脑进行嵌入式开发板的测试&#xff0c;主要的原因有两个&#xff1a;一是平时使用的笔记本资源过于紧张&#xff0c;二是方便移动办公&#xff0c;这样我只要平时拿着开…

解锁阿里巴巴1688数据宝藏:API助力批量获取商品价格、标题、图片及库存

在数字化时代&#xff0c;数据已成为商业决策的重要依据。对于电商从业者来说&#xff0c;掌握商品的价格、标题、图片及库存等关键信息&#xff0c;是优化销售策略、提升竞争力的关键。阿里巴巴1688平台作为国内领先的B2B电商平台&#xff0c;其海量的商品数据为商家提供了丰富…

DRF的认证、权限、限流、序列化、反序列化

DRF的认证、权限、限流、序列化、反序列化 一、认证 1、直接用&#xff0c;用户授权 实现方法 编写 ->认证组件 应用组件 编写 ->认证组件 from rest_framework.authentication import BaseAuthentication from rest_framework.exceptions import AuthenticationF…

基于opencv的视觉巡线实现

前言 这段时间在和学弟打软件杯的比赛&#xff0c;有项任务就是机器人的视觉巡线&#xff0c;这虽然不是什么稀奇的事情&#xff0c;但是对于一开始不了解视觉的我来说可以说是很懵了&#xff0c;所以现在就想着和大家分享一下&#xff0c;来看看是如何基于opencv来实现巡线的…