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…

开发语言漫谈-C#

C#的#&#xff0c;字面上的意思就是&#xff0c;也就是把C再。微软只所以搞C#就是要抗衡Java。微软当时搞了个J&#xff0c;被Java告了&#xff0c;没办法了只能另取炉灶。从纯技术角度来看&#xff0c;C#设计非常优秀&#xff0c;可以覆盖所有领域&#xff0c;是几乎唯一的全栈…

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

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

.Net <% %>

<% %> 语法 : <% import namespace"system.data"%> 用来导入后台命名空间 指令用于指定当页和用户控件编译器处理 ASP.NET Web 窗体页 (.aspx) 和用户控件 (.ascx) 文件时所使用的设置。<% %> 语法 : <% name %> <% getstr() %&g…

修改el-button按钮背景色后,按钮失去了elementUI原有的hover和active的效果

应完整修改为&#xff1a; <el-button type"primary" icon"el-icon-plus" click"addUser">新增用户</el-button>.el-button--primary:not(.is-disabled) {background-color: #1174de;border-color: #1174de;&:hover {&:not…

尝试在手机上运行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;最终得到的序列就是已经排…

使用opencv + ffmpeg 开发视频播放器Demo

使用opencv ffmpeg 开发视频播放器Demo #include <opencv2/opencv.hpp> #include <opencv2/highgui.hpp> #include <opencv2/videoio.hpp>extern "C" { #include <libavformat/avformat.h> #include <libavcodec/avcodec.h> #includ…

【LeetCode热题100】【二叉树】将有序数组转换为二叉搜索树

题目链接&#xff1a;108. 将有序数组转换为二叉搜索树 - 力扣&#xff08;LeetCode&#xff09; 取中间的数作为根节点&#xff0c;左边的数递归转换&#xff0c;右边的数递归转换 class Solution { public:TreeNode *sortedArrayToBST(vector<int> &nums) {retur…

通过 Spark SQL 和 DataFrames 与外部数据源交互

文章目录 前言Spark SQL 与 HiveUDF 通过 Spark SQL Shell, Beeline 和 Tableau 查询Spark SQL ShellBeelineTableau 外部数据源通过 JDBC 连接数据库PostgreSQLMySQL 高阶函数Explode 和 CollectUDF内置函数高阶函数 常用 DataFrames 和 Spark SQL 操作总结 前言 Spark 的数据…

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

隐私计算实训营第九讲-隐语多方安全计算在安全核对的行业实践 文章目录 隐私计算实训营第九讲-隐语多方安全计算在安全核对的行业实践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方式会检查包含的文件是否已经被…

口语教育的黄金时代:AI技术引领教育创新与创业机遇

这些人的赚钱思路是真灵活&#xff01; 这几天刷到艾维奇采访之昊的视频&#xff0c;做口语教育真赚钱&#xff0c;lv的包包随便买&#xff0c;住大房子&#xff0c;三辆车&#xff0c;有评论晒图一个九百的课&#xff0c;卖了1.3万份&#xff0c;直接千万到账。 然后我又想到…

TCP重传机制总结

超时重传概念 超时重传&#xff1a;发送方每发送一个数据包&#xff0c;就会为这个数据包设置一个超时时间&#xff0c;如果在时间内没收到应答这个数据包的ACK包&#xff0c;需要重新发送这个数据包&#xff1b;每次重传后&#xff0c;RTO会成倍增加&#xff0c;且重传次数有…

python-pytorch实现skip-gram 0.5.000【直接可运行】

python-pytorch实现skip-gram 0.5.000【直接可运行】 参考导入包加载数据和切词获取wordList、raw_text获取vocab、vocab_sizeword_to_idx、idx_to_word准备训练数据准备模型和参数训练模型保存模型简单预测获取训练后的词向量画图看下分布利用词向量计算相似度余弦点积 参考 …