当前位置: 首页 > news >正文

C++学习记录——이십팔 C++11(4)

文章目录

  • 包装器
    • 1、functional
    • 2、绑定


这一篇比较简短,只是因为后要写异常和智能指针,所以就把它单独放在了一篇博客,后面新开几篇博客来写异常和智能指针

包装器

1、functional

包装器是一个类模板,对可调用对象类型进行再封装适配,可调用对象,比如函数指针,lambda等。包装器的头文件是functional。

template <class T> function;
template <class Ret, class... Args>
class function<Ret(Args...)>
模板参数说明:
Ret:被调用函数的返回类型
Args...:被调用函数的形参

实际使用

int f(int a, int b)
{cout << "f" << endl;return a + b;
}struct Functor
{
public:int operator() (int a, int b){cout << "Functor" << endl;return a + b;}
};int main()
{//int(*pf1)(int, int) = f;函数指针function<int(int, int)> f1 = f;function<int(int, int)> f2 = Functor();function<int(int, int)> f3 = [](int a, int b) {cout << "lambda" << endl;return a + b; };cout << f1(1, 2) << endl;cout << f2(10, 20) << endl;cout << f3(100, 200) << endl;return 0;
}

三个int,第一个是函数返回值类型,后两个是参数类型。包装起包装起来的就可以传给模板参数

	map<string, function<int(int, int)>> opFuncMap;opFuncMap["函数指针"] = f1;opFuncMap["仿函数"] = Functor();opFuncMap["lambda"] = [](int a, int b) {cout << "lambda" << endl;return a + b;};cout << opFuncMap["lambda"](1, 2) << endl;

看一个题

逆波兰表达式求值

给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。

请你计算该表达式。返回一个表示表达式值的整数。

注意:

有效的算符为 ‘+’、‘-’、‘*’ 和 ‘/’ 。
每个操作数(运算对象)都可以是一个整数或者另一个表达式。
两个整数之间的除法总是 向零截断 。
表达式中不含除零运算。
输入是一个根据逆波兰表示法表示的算术表达式。
答案及所有中间计算结果可以用32位整数表示。

在这里插入图片描述

在这里插入图片描述

之前的写法

class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;for(auto& str : tokens){if(str == "+" || str == "-" || str == "/" || str == "*"){int right = st.top();st.pop();int left = st.top();st.pop();switch(str[0]){case '+':st.push(left+right);break;case '-':st.push(left-right);break;case '*':st.push(left*right);break;case '/':st.push(left/right);break;}}else{st.push(stoi(str));}}return st.top();}
};

用包装器后

class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;map<string, function<int(int, int)>> opFuncMap = {{"+", [](int a, int b){return a + b; }},{"-", [](int a, int b){return a - b; }},{"*", [](int a, int b){return a * b; }},{"/", [](int a, int b){return a / b; }}};//这里就是map的初始化,用C++11的列表初始化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();}
};

包装器也可以包装成员函数。

class Plus
{
public:static int plus1(int a, int b){return a + b;}double plus2(double a, double b){return (a + b) * _rate;}
private:int _rate = 2;
};int main()
{
class Plus
{
public:Plus(int rate = 2):_rate(rate){}static int plus1(int a, int b){return a + b;}double plus2(double a, double b){return (a + b) * _rate;}
private:int _rate = 2;
};int main()
{function<int(int, int)> f1 = Plus::plus1;function<int(Plus, double, double)> f2 = &Plus::plus2;cout << f1(1, 2) << endl;cout << f2(Plus(), 20, 20) << endl;Plus p1(3);cout << f2(p1, 20, 20) << endl;return 0;
}

静态成员函数可以直接调用,而非静态的需要在第一个位置加上类名,因为有this指针,然后后面的Plus前加上&,静态函数也可以加上这个&,使用这个函数的时候,非静态需要在第一个参数位置放上类的对象,可以是匿名对象,如果在声明f2时,传的是*Plus,那么下面调用时就必须传对象的地址,所以就不能传匿名对象的地址,因为右值无法取地址。

包装器本质上是仿函数,f1,f2,f3就是对象,然后调用operator(),传过去参数,然后operator()再去调用对应函数,传类的对象就用对象来调用,传指针就指针来调用。

2、绑定

绑定是一个函数模板,用来调整参数。绑定是一个通用的函数适配器,接受一个可调用对象,可调用对象就是三个,函数指针、lambda、仿函数,生成一个新的可调用对象来适配。

bind函数第一个参数是一个万能引用,左右值都可传,然后后面的是占位符,_1表示第一个参数,_2表示第二个参数,以此类推,这些占位符是一个placeholders空间里。

int Print(int a, int b)
{cout << a << " ";cout << b << endl;
}int main()
{Print(10, 20);auto RP = bind(Print, placeholders::_2, placeholders::_1);RP(10, 20);//再次调用就换了顺序了。return 0;
}

如果bind写着_1在_2前面,那就没换顺序,要换顺序占位符就得对应着写。bind函数会返回一个对象,我们可以用auto来推演类型,还可以用function<void(int, int)>。实际调用的还是Print,不过适配器就是套了一个壳。

绑定真正有用的是改变参数个数

用这段代码做例子

class Sub
{
public:Sub(int rate):_rate(rate){}int func(int a, int b){return (a - b) * _rate;}
private:int _rate;
};class Solution {
public:int evalRPN(vector<string>& tokens) {stack<int> st;map<string, function<int(int, int)>> opFuncMap ={{"+", [](int a, int b) {return a + b; }},{"-", [](int a, int b) {return a - b; }},{"*", [](int a, int b) {return a * b; }},{"/", [](int a, int b) {return a / b; }}};//这里就是map的初始化,用C++11的列表初始化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();}
};int main()
{function<int(Sub, int, int)> fSub = &Sub::func;fSub(Sub(1), 10, 20);return 0;
}

这是上面包装器的写法。这样的写法无法给opFuncMap传fSub对象,因为参数个数不一致,这时候就是绑定的作用体现了。

	function<int(int, int)> fSub = bind(&Sub::func, Sub(1), placeholders::_1, placeholders::_2);fSub(10, 20);

把Sub(1)对象显式地传给func函数,顺序没有变,只是第一个参数显示传,剩下两个就从_1开始排顺序。也可以对其他参数来绑定。

	function<int(int, int)> fSub = bind(&Sub::func, placeholders::_1, 10, placeholders::_2);fSub(Sub(1), 20);

本篇gitee

结束。

相关文章:

C++学习记录——이십팔 C++11(4)

文章目录 包装器1、functional2、绑定 这一篇比较简短&#xff0c;只是因为后要写异常和智能指针&#xff0c;所以就把它单独放在了一篇博客&#xff0c;后面新开几篇博客来写异常和智能指针 包装器 1、functional 包装器是一个类模板&#xff0c;对可调用对象类型进行再封装…...

UE学习记录03----UE5.2 使用拖拽生成模型

0.创建蓝图控件&#xff0c;自己想要展示的样子 1.侦测鼠标拖动 2.创建拖动操作 3.拖动结束时生成模型 3.1创建actor , 创建变量EntityMesh设为可编辑 生成Actor&#xff0c;创建变量EntityMesh设为可编辑 屏幕鼠标位置转化为3D场景位置 4.将texture设置为变量并设为可编辑&am…...

Spring Cache框架(缓存)

1、介绍&#xff1a; Spring Cache 是一个框架&#xff0c;实现了基于注解的缓存功能&#xff0c;只需要简单加个注解&#xff0c;就能实现缓存功能。它提供了一层抽象&#xff0c;底层可以切换不同的cache实现。具体就是通过CacheManager 接口来实现不同的缓存技术。 针对不同…...

Linux学习之Ubuntu 20使用systemd管理OpenResty服务

sudo cat /etc/issue可以看到操作系统的版本是Ubuntu 20.04.4 LTS&#xff0c;sudo lsb_release -r可以看到版本是20.04&#xff0c;sudo uname -r可以看到内核版本是5.5.19&#xff0c;sudo make -v可以看到版本是GNU Make 4.2.1。 需要先参考我的博客《Linux学习之Ubuntu 2…...

[数据集][目标检测]疲劳驾驶数据集VOC格式4类别-4362张

数据集格式&#xff1a;Pascal VOC格式(不包含分割的txt文件&#xff0c;仅仅包含jpg图片和对应的xml) 图片数量(jpg文件个数)&#xff1a;4362 标注数量(xml文件个数)&#xff1a;4362 标注类别数&#xff1a;4 标注类别名称:["closed_eye","closed_mouth"…...

matlab使用教程(25)—常微分方程(ODE)选项

1.ODE 选项摘要 解算 ODE 经常要求微调参数、调整误差容限或向求解器传递附加信息。本主题说明如何指定选项以及每个选项与哪些微分方程求解器兼容。 1.1 选项语法 使用 odeset 函数创建 options 结构体&#xff0c;然后将其作为第四个输入参数传递给求解器。例如&#xff0…...

MybatisPlus简单到入门

一、MybatisPlus简介 1、入门案例&#xff08;重点&#xff09;&#xff1a; 1.SpringBoot整合MP1).创建新模块选择&#xff0c;Spring项初始化。2).选择当前模块使用的技术&#xff0c;只保留MySQL Driver就行&#xff0c;不要选择mybatis避免与后面导入mybatisPlus的依赖发…...

9. 优化器

9.1 优化器 ① 损失函数调用backward方法&#xff0c;就可以调用损失函数的反向传播方法&#xff0c;就可以求出我们需要调节的梯度&#xff0c;我们就可以利用我们的优化器就可以根据梯度对参数进行调整&#xff0c;达到整体误差降低的目的。 ② 梯度要清零&#xff0c;如果梯…...

go学习之流程控制语句

文章目录 流程控制语句1.顺序控制2.分支控制2.1单分支2.2双分支单分支和双分支的四个题目switch分支结构 3.循环控制for循环控制while 和do...while的实现 4.跳转控制语句breakcontinuegotoreturngotoreturn 流程控制语句 介绍&#xff1a;在程序中&#xff0c;程序运行的流程…...

docker基于已有容器和通过Dockerfile进行制作镜像配置介绍

目录 一.制作镜像的两种方式 1.在已有容器中更新并提交这个镜像 2.使用Dockerfile来制作 二.基于容器制作镜像 1.格式 &#xff08;1&#xff09;主要格式 &#xff08;2&#xff09;可选参数 2.案例 基于容器创建镜像设置标签并进行验证是否可用 &#xff08;1&…...

2022年09月 C/C++(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

第1题&#xff1a;最长上升子序列 一个数的序列bi&#xff0c;当b1 < b2 < … < bS的时候&#xff0c;我们称这个序列是上升的。对于给定的一个序列(a1, a2, …, aN)&#xff0c;我们可以得到一些上升的子序列(ai1, ai2, …, aiK)&#xff0c;这里1 < i1 < i2 &…...

二级MySQL(九)——表格数据处理练习

在Mysql中&#xff0c;可以用INSERT或【REPLACE】语句&#xff0c;向数据库中已一个已有的表中插入一行或多行记录。 在Mysql中&#xff0c;可以用【DELETE】或【TRUNCATE】语句删除表中的所有记录。 在Mysql中&#xff0c;可以用【UPDATE】语句来修改数据表中的记录。 为了完…...

QT ListQvector at赋值出错以及解决办法 QT基础入门【QT存储结构】

1、问题 error: passing const QString as this argument discards qualifiers error: assignment of read-only location vec.QVector<int>::at(0) 在Qt中QList,Qvector一般获取元素都是通过at(index)来获取,但是at()的返回是一个const & 常引用,也就是元素不支…...

STM32 CubeMX (H750)RGB屏幕 LTDC

STM32 CubeMX STM32 RGB888 LTDC STM32 CubeMX一、STM32 CubeMX 设置时钟树LTDC使能设置屏幕参数修改RGB888的GPIO 二、代码部分效果 RGB屏幕线束定义&#xff1a; 一、STM32 CubeMX 设置 时钟树 这里设置的时钟&#xff0c;关于刷新速度 举例子&#xff1a;LCD_CLK24MHz 时…...

Redis问题集合(三)在Redis容器里设置键值对

前言 前提是已经拉取了Redis镜像并创建了对应的容器做个记录&#xff0c;方便后续查看 步骤 查看Redis容器的ID&#xff1a;docker ps -a 进入容器&#xff1a;docker exec -it 容器ID /bin/bash进入redis命令行&#xff1a;redis-cli输入密码&#xff1a;auth 配置密码 查看…...

spark中排查Premature EOF: no length prefix available

报错信息 /07/22 10:20:28 WARN DFSClient: Error Recovery for block BP-888461729-172.16.34.148-1397820377004:blk_15089246483_16183344527 in pipeline 172.16.34.64:50010, 172.16.34.223:50010: bad datanode 172.16.34.64:50010 [DataStreamer for file /bdp/data/u9…...

numpy高级函数之where和extract函数

1 numpy.where() 函数返回输入数组中满足给定条件的元素的索引 ---------------------------------------------------- 代码&#xff1a; n1np.random.randint(10,20,10) n2np.where(n1>15) 结果&#xff1a; [17 15 19 15 12 10 16 11 15 13] #原始数组 (array([…...

用Python写一个武侠游戏

前言 在本教程中&#xff0c;我们将使用Python写一个武侠类的游戏&#xff0c;大的框架全部搭好了&#xff0c;很多元素都可以自己添加&#xff0c;让游戏更丰富 &#x1f4dd;个人主页→数据挖掘博主ZTLJQ的主页 个人推荐python学习系列&#xff1a; ☄️爬虫JS逆向系列专栏 -…...

Java --- 异常处理

目录 一、什么是异常 二、异常抛出机制 三、如何对待异常 四、 Java异常体系 4.1、Throwable 4.2、Error 4.2、Exception 4.2.1、编译时异常 4.2.2、运行时期异常 五、异常处理 5.1、捕获异常&#xff08;try-catch&#xff09; 5.1.2、catch中异常处理方式 …...

CDN/DCDN(全站加速)排查过程中如何获取Eagle ID/UUID

目录 前言1.通过浏览器直接访问文件时获取Request ID 前言 阿里云CDN/DCDN(全站加速)为接收到的每个请求分配唯一的服务器请求ID&#xff0c;作为关联各类日志信息的标识符。当您在使用CDN/DCDN(全站加速)过程中遇到错误且希望阿里云技术支持提供协助时&#xff0c;需要提交失…...

基于算法竞赛的c++编程(28)结构体的进阶应用

结构体的嵌套与复杂数据组织 在C中&#xff0c;结构体可以嵌套使用&#xff0c;形成更复杂的数据结构。例如&#xff0c;可以通过嵌套结构体描述多层级数据关系&#xff1a; struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...