C++11新特性包装器

article/2025/7/26 10:09:23

目录

1.function

2。  150. 逆波兰表达式求值

​编辑


1.function

C++11中提供了新的类模板function,它是一个包装器,可以包装其它可以存储调用其它的可调用对象,这里的可调用对象包括函数指针,仿函数,.lambda,bind表达式等,存储的可调用对象被称为function目标,若function不含目标,则城它为空,会抛出异常。

function的链接被包含在头文件<functional>中,我们在cpp中包含这个文件可以去使用function了。

函数指针,仿函数,lambda等可调用对象的类型各不相同,function的优势就是统一类型,对它们都进行包装,这样在很多地方就可以方便使用可调用对象。

我们可以看到下面的例子,function说实话,它就是一个包装器,它把add函数包装成()形式去调用,但实际调用的还是原函数的地址,我们打印出两次调用add的地址发现它们相同,所以得出结论,function包装了add来进行()的统一调用,对于lambda,仿函数亦是如此。

#include<iostream>
using namespace std;
#include<functional>
int add(int a, int b)
{cout << add<<endl;return a + b;
}
int main()
{int a = add(1, 2);function<int(int, int)>f = add;int b=f(1, 2);return 0;
}

在文件中我们可以看到function实际上用了一个参数包和特化来实现。R是返回类型,参数包里是传参类型。下面我们再写一下仿函数,lambda的function包装怎么写。

这里其实我们function等号右边其实要写函数地址,只是普通函数函数名会自动取地址我们不用手动写,但是类中定义的普通成员函数需要写,这里C++对于类中的成员函数提供了两种方式,一种是传对象,一种是传对象地址,因为类中的普通成员函数第一个隐藏参数是this指针,方便知道是哪个对象调用了它,所以我们得给出对象或者对象地址。

至于lambda是这样写的function<int(int, int)> f3 = [](int a, int b) {return a + b; };

类的成员函数我们分别写了对象和对象地址两种,c++对于这两种写法都是支持的,对象通过.*去回调成员函数,对象地址通过->去回调成员函数,所以支持了这两种写法。本质function它就是一个包装器,它对原函数没有改变,调用的函数还是原函数,只是包装成()统一调用了。

#include<functional>
int f(int a, int b)
{
return a + b;
}
struct Functor
{
public:
int operator() (int a, int b)
{
return a + b;
}
};
class Plus
{
public:
Plus(int n = 10)
:_n(n)
{}
static int plusi(int a, int b)
{
return a + b;
}
double plusd(double a, double b)
{
return (a + b) * _n;
}
private:
int _n;
};
int main()
{
// 包装各种可调⽤对象
function<int(int, int)> f1 = f;
function<int(int, int)> f2 = Functor();
function<int(int, int)> f3 = [](int a, int b) {return a + b; };
cout << f1(1, 1) << endl;
cout << f2(1, 1) << endl;
cout << f3(1, 1) << endl;
// 包装静态成员函数
// 成员函数要指定类域并且前⾯加&才能获取地址
function<int(int, int)> f4 = &Plus::plusi;
cout << f4(1, 1) << endl;
// 包装普通成员函数
// 普通成员函数还有⼀个隐含的this指针参数,所以绑定时传对象或者对象的指针过去都可以
function<double(Plus*, double, double)> f5 = &Plus::plusd;
Plus pd;
cout << f5(&pd, 1.1, 1.1) << endl;
function<double(Plus, double, double)> f6 = &Plus::plusd;
cout << f6(pd, 1.1, 1.1) << endl;
cout << f6(pd, 1.1, 1.1) << endl;
function<double(Plus&&, double, double)> f7 = &Plus::plusd;
cout << f7(move(pd), 1.1, 1.1) << endl;
cout << f7(Plus(), 1.1, 1.1) << endl;
return 0;
}

这里我们如果传对象调用实际上去通过.*去回调成员函数了,编译器明白是哪个对象来调这个成员函数。我们给对象地址编译器也可以通过->去调用成员函数,所以这两种方法都是通过回调成员函数去调的。

  • obj.*​ 用于 ​​对象实例​​ 调用成员指针。
  • obj->*​ 用于 ​​对象指针​​ 调用成员指针。
  • 成员指针(函数/变量)在 ​​动态绑定、回调、泛型编程​​ 中很有用。
  • #include <iostream>
    using namespace std;class Student {
    public:string name;int age;Student(string n, int a) : name(n), age(a) {}
    };int main() {Student s("Alice", 20);Student* sPtr = &s;// 定义成员变量指针string Student::*namePtr = &Student::name;int Student::*agePtr = &Student::age;// 使用 obj.*cout << "Name: " << s.*namePtr << ", Age: " << s.*agePtr << endl;// 使用 obj->*cout << "Name: " << sPtr->*namePtr << ", Age: " << sPtr->*agePtr << endl;return 0;
    }

    2150. 逆波兰表达式求值

  • 我们传统做法是用栈来做,遇到数字入栈,遇到运算符出栈运算。得到最后结果。代码如下:
    class Solution {
    public:int evalRPN(vector<string>& tokens) {stack<int>nums;auto it = tokens.begin();while (it != tokens.end()){if (*it == "+"){int tmp = nums.top();nums.pop();int tmp1 = nums.top();nums.pop();nums.push(tmp + tmp1);}else if (*it == "-"){int tmp = nums.top();nums.pop();int tmp1 = nums.top();nums.pop();nums.push(tmp1 - tmp);}else if (*it == "*"){int tmp = nums.top();nums.pop();int tmp1 = nums.top();nums.pop();nums.push(tmp1 * tmp);}else if (*it == "/"){int tmp = nums.top();nums.pop();int tmp1 = nums.top();nums.pop();nums.push(tmp1 / tmp);}else {nums.push(stoi(*it));}it++;}return nums.top();}
    };

    学了function和lambda之后我们可以简化代码,利用map的映射来解决问题:

  • class Solution {
    public:
    int evalRPN(vector<string>& tokens) {
    stack<int> st;
    // function作为map的映射可调⽤对象的类型
    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;}}
    };
    for(auto& str : tokens)
    {
    if(opFuncMap.count(str)) // 操作符
    {
    int right = st.top();
    st.pop();
    int left = st.top();
    st.pop();
    int ret = opFuncMap[str](left, right);
    st.push(ret);
    }
    else
    {
    st.push(stoi(str));
    }
    }
    return st.top();
    }
    };


http://www.hkcw.cn/article/doQLjctgLO.shtml

相关文章

标准精读:2025 《可信数据空间 技术架构》【附全文阅读】

《可信数据空间 技术架构》规范了可信数据空间的技术架构,明确其作为国家数据基础设施的定位,以数字合约和使用控制技术为核心,涵盖功能架构(含服务平台与接入连接器的身份管理、目录管理、数字合约管理等功能)、业务流程(登记、发现、创建空间及数据流通利用)及安全要求…

免费文件批量重命名工具推荐

软件介绍 本文介绍一款专业的文件批量命名工具——文件批量更名。 软件特点 这款软件完全免费使用&#xff0c;没有任何广告干扰&#xff0c;操作简单方便。 软件安装与体积 它无需安装&#xff0c;下载后即可直接使用&#xff0c;软件体积非常小巧&#xff0c;仅880KB。 …

GD32F103系列FreeRTOS移植并测试案例

1 首先准备一份上一个博客里的GD32F103C8T6的工程模版 2 从 FreeRTOS官网下载源码&#xff0c;链接如下 FreeRTOS™ - FreeRTOS™ 博主下载的是这一版本 FreeRTOSv202406.01-LTS.zip 这两份文件都会上传CSDN资源&#xff0c;或者需要的私聊&#xff0c;下面正式开…

Redis分布式锁深度解析与最佳实践

1 2 Redis分布式锁实现方式确实是经典问题&#xff0c;下面我将系统性地分析这个方案及其演进过程&#xff0c;并给出生产级的解决方案。 一、基础方案及其缺陷 1. 初始实现方式 SETNX lock_key unique_value # 尝试获取锁 EXPIRE lock_key 30 # 设置过期时间 …

业内:A股市场或迎来新一轮“反弹” 科技股领涨显现活力

中美之间的科技竞争非常激烈。美国近期采取了一系列措施,甚至提出了让中概股从美股市场退出的想法。对此,中国证监会本周表示,将为科技企业境外上市提供更加透明、高效且可预期的监管政策。过去几年,中概股在海外市场经历了巨大的波动。美国对审计底稿的要求越来越严格,导…

盟友为何不再信任美国了 美方言行不一引质疑

2025年新加坡香格里拉对话会结束。清华大学战略与安全研究中心研究员、退役空军大校周波已经连续十几年参加这一论坛,并长期参与中国对外舆论斗争。他在一周前接受澳大利亚媒体采访时,被问到“如果中澳爆发冲突,谁会赢?”时,直接回应“你们必输”,引起广泛关注。今年的“…

周深让你穿雨衣没让你穿这款 萌系造型笑翻全场

周深南京演唱会遭遇大雨,粉丝们纷纷建议他穿雨衣防雨。没想到,他竟然选择了一件亮黄色的儿童款小黄鸭雨衣,这一造型让现场观众捧腹大笑。2025年6月1日,周深在南京的演唱会上,连续两天的大雨并未影响他的心情。他身穿一件亮黄色的小黄鸭雨衣,蹦蹦跳跳地登台,瞬间点燃了现…

菲律宾防长说中国记者是特工 南海风波再起

最近,菲律宾的一些非政府组织在中国南海海域活动频繁。经过调查,发现这些组织的资金链背后有美国资助的迹象,这似乎揭示了反华机构的新手段。然而,在与菲律宾国防部长对质时,他却情绪激动,直接指责记者为“特工”。责任编辑:zx0001

openssl 怎么生成吊销列表

mkdir test cd test # cp /etc/ssl/openssl.cnf ./ # 根据 /usr/lib/ssl/openssl.cnf 配置文件中目录结构可知有个demoCA目录&#xff0c;目录下有各种文件。 mkdir ./demoCA ./demoCA/newcerts ./demoCA/private sudo chmod 777 -R ./demoCA/ echo 01 > ./demoCA/serial to…

抖音客户端训练营--day2

常见的布局 布局的选择依赖于对性能的需求&#xff0c;其中约束布局的效果最好&#xff0c;但是学习成本高 帧布局 是最简单的布局容器&#xff0c;将所有的子元素堆叠在一起&#xff0c;默认放置在左上角&#xff0c;新添加的元素会覆盖在之前元素的上方&#xff0c;形成层叠…

郑钦文胜利后发文送儿童节祝福 首次闯进法网八强

北京时间6月1日,在2025年法国网球公开赛女单第四轮比赛中,中国选手郑钦文击败俄罗斯球员萨姆索诺娃,首次闯进法网女单八强。赛后,她难掩激动心情,在场边与观众一同唱起歌曲《日不落》,现场气氛热烈。这一幕有其缘起。在上一轮比赛中,郑钦文击败姆博科晋级16强后,在社交…

不要一直坐着!研究发现久坐时间越长,患痴呆风险更大 老年朋友需特别注意

在快节奏的现代生活中,少坐多动似乎成了难以实现的目标。久坐已成为很多人的常态,尤其是老年人,由于身体状况不佳、缺乏社交和活动兴趣,养成了长期久坐的习惯。然而,这种看似平常的行为对老年人的健康产生了重大影响。近期发表的两项研究探讨了久坐对老年人认知功能和心血…

端午假期后天气 南北差异明显

端午假期(5月31日至6月2日)即将到来,作为传统节日,赛龙舟、包粽子等民俗活动丰富多彩。今年假期恰逢六一儿童节,亲子游和短途游的热情也格外高涨。中国天气网推出了2025年全国端午假期天气地图和十大热门出游地晴雨表,帮助大家了解出行所需装备。从天气地图来看,北方大部…

网传赵丽颖将客串九门 热度背后引思考

最近,娱乐圈再次掀起热议,网传赵丽颖将客串《九门》,消息迅速登上热搜,引发粉丝和网友的热烈讨论。然而,在这波热度背后,值得我们冷静思考的是,这样的炒作是否真的有必要。《九门》已经官宣了新女主陈瑶,她为诠释霍仙姑一角付出了诸多努力,从研读剧本到练习民国礼仪都…

距今约3万年的山顶洞人身高曝光 远古人类身高新发现

近日,一项关于山顶洞人的研究成果引发热议。研究显示,距今约3万年的山顶洞人男性平均身高约为1.74米,女性约为1.59米,与现代人身高非常接近。这一发现仿佛打开了一扇穿越时空的大门,让人们得以一窥远古人类的生活。山顶洞人在人类进化史上占据重要地位。与更早的北京猿人相…

马斯克称政府效率部成了替罪羊 裁员责任全推卸

当地时间6月1日,美国企业家埃隆马斯克在接受哥伦比亚广播公司采访时表达了他对美国政府的态度。他表示自己不想公开反对政府,但也不愿意为政府的所有行为承担责任。他提到,由他领导的“政府效率部”成为了所有问题的替罪羊,无论是真实的还是虚构的裁员事件都被归咎于该部门…

听航天专家揭秘天问二号任务 探秘小行星取样返回

我国在西昌卫星发射中心用长征三号乙运载火箭成功发射了行星探测工程天问二号探测器。火箭飞行约18分钟后,将探测器送入地球至小行星2016HO3的转移轨道。随后,探测器太阳翼正常展开,标志着发射任务圆满成功。天问二号是我国首次实施的行星际取样返回任务,旨在对小行星2016H…

【PyQt5】PyQt5初探 - 一个简单的例程

PyQt5初探 - 一个简单的例程 引言一、安装配置二、使用2.1 PyQt5简单例程2.2 与c Qt深入对比 三、相关教程 引言 PyQt5是一个比较流行的Python图形用户界面(GUI)库&#xff0c;它基于Qt库&#xff08;一个跨平台的C库&#xff0c;用于开发应用程序的图形界面&#xff09;为Pyt…

复数的指数形式:MATLAB演示

复数的指数形式&#xff1a;MATLAB演示 复数在工程和科学计算中无处不在&#xff0c;而指数形式&#xff08;又称极坐标形式&#xff09;是表示和处理复数的一种强大方式。本文将介绍复数的指数形式表示法&#xff0c;并展示如何使用MATLAB进行相关计算和可视化。 复数的基础…

FastAPI MCP 快速入门教程

目录 什么是 FastAPI MCP&#xff1f;项目设置1. 初始化项目2. 安装依赖3. 项目结构 编写代码创建主应用文件 运行和测试1. 启动服务器2. 使用 MCP Inspector 测试 什么是 FastAPI MCP&#xff1f; FastAPI MCP 是一个将 FastAPI 应用程序转换为 Model Context Protocol (MCP)…