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

C++高级特性:柯里化过程与std::bind(六)

1、柯里化过程
1.1、operator()的引入

现在需要完成这样一个需求:有一个函数每次调用返回的结果不一样。例如:两次调用的返回值都不一样那么就可以达到这种目的

1.1.1、简单点的写法

可以给一个全局的变量(静态变量),每次调用对这个全局变量进行值的修改然后返回,这样每次返回都不一样。

#include <iostream>
int nums;
int func()
{return ++nums;
}int main() {std::cout << "Hello, World!" << std::endl;std::cout << std::boolalpha << (func() == func()) << std::endl;return 0;
}
1.1.2、operator()重载

如果需要用类来完成,那么可以使用operator()仿函数来做,仿函数其实是一个特殊的函数。

class Functor{
public:int x;int operator()(){return ++x;}
};
void test2()
{Functor func;std::cout << std::boolalpha << (func() == func()) << std::endl;
}
1.2、Chain Adding

有了上面的基础,可以看这样一个题目:

  • 打算创建一个函数,这个函数能够完成类似于add(1) = 1、add(1)(2) = 3、add(1)(2)(3) = 6…类似于这种求和的操作。
  • 并且能够判断出add(1) == 1这种判断也能完成,以及add(1) + 3、add(1) - 3
  • 意思没出现一个括号就会对之前的值进行一个加法和减法

通过分析可以看到add(1)应该返回一个类似函数的东西func,然后这个东西还可以继续func(2)…可以尝试使用上面的仿函数来继续,

  • 很明显这里有一个链式编程的东西,返回的东西应该是一个类对象本身的引用这样就可以继续链式,当然也可以返回一个普通类型但是要做好拷贝构造。
  • 对于不同类型的比较,那么肯定需要重载一下==符号进行判断值是否相等即可。
  • 对于第三个操作很明显需要重载加减法么,一样需要注意返回引用或者拷贝构造的对象。
  • 思考:如果需要流输出类对象应该怎么做呢?答案:重载输出流
  • 补充:其实还可以把类型进行重载,把当前类中的返回类型重载为int可以直接省略判断、加减和输出操作
class Functor{
public:int sum;Functor(): sum(0){}Functor(int x): sum(x){}Functor& operator()(int val){this->sum += val;return *this;}bool operator== (const int x) const{return sum == x;}Functor& operator-(int x){this->sum -= x;return *this;}Functor& operator+(int x){this->sum += x;return *this;}friend std::ostream & operator<<(std::ostream& out, const Functor& functor){out << functor.sum << std::endl;return out;}
//    operator int() {							//可以直接替换 == 重载、 加减法、输出流
//        return this->sum;
//    }
};int main()
{Functor f1;f1(1);std::cout << f1.sum << std::endl;Functor f2;f2(1)(2);std::cout << f2.sum << std::endl;Functor f3;std::cout << std::boolalpha << (f3(1) == 1)<< std::endl;Functor f4(1);f4 = f4 - 2;f4 = f4 + 5;std::cout << f4.sum << std::endl;std::cout << f4 << std::endl;return 0;
}

其实这是一个很好的例子,可以帮助我们理解重载的意义和C++面向对象的灵活使用。

1.3、柯里化过程

其实上面的链式编程或者函数式编程就是一个柯里化的过程,其实这种操作在lambda表达式也有体现的,lambda表达式中继续lambda表达式

// add(1, 2)     -->   add(1)(2)
void test4()
{auto add = [](int x)->auto{return [x](int y) -> auto{return x + y;};};std::cout << add(1)( 2) << std::endl;
}
2、std::bind
  • 有了上面函数式编程和柯里化的过程,理解bind就很简单了。
  • std::bind主要用于给函数进行参数绑定的
#include <iostream>
#include <functional>int add(int a, int b)
{std::cout << "a = " << a << ", b = " << b <<std::endl;return a + b;
}
int main()
{using namespace std::placeholders;auto f1 = std::bind(add, 1, _1);std::cout << f1(2) << std::endl;auto f2 = std::bind(add, _1, 1);std::cout << f2(2) << std::endl;std::cout << std::bind(add, 1, _1)(2) << std::endl;std::cout << std::bind(add, _1, _2)(3, 4) << std::endl;std::cout << std::bind(add, _2, _1)(3, 4) << std::endl;std::cout << std::bind(add, _1, _1)(3, 4) << std::endl;std::cout << std::bind(add, _2, _2)(3, 4) << std::endl;// C++20标准
//    std::cout << std::bind_front(add, 1)(2) << std::endl;// C++23标准
//    std::cout << std::bind_back(add, 2)(1) << std::endl;return 0;
}

在这里插入图片描述

  • 为了给bind参数绑定需要引入命名空间中的using name std::placeholders占位符宏
  • 通过_i来表示第几个参数,其中最明显的是一绿框和黑框中的
    • 绿框:根据传入的占位符宏的编号索引到对应的值,_2表示取参数列表的第2个参数、依次类推
    • 黑框:当参数列表为X个时,可以使用的宏为_i <= X,同时可以多个参数绑定同一个宏
  • 和std::move一样可能现在对这个概念还不是很熟悉,等到完美转发forward的时候会更加清楚的理解bind和move

相关文章:

C++高级特性:柯里化过程与std::bind(六)

1、柯里化过程 1.1、operator()的引入 现在需要完成这样一个需求&#xff1a;有一个函数每次调用返回的结果不一样。例如&#xff1a;两次调用的返回值都不一样那么就可以达到这种目的 1.1.1、简单点的写法 可以给一个全局的变量&#xff08;静态变量&#xff09;&#xff…...

vmware虚拟机补救

更新了虚拟机里面工具和资料&#xff0c;进行了磁盘整理和压缩&#xff0c;虚拟机运行进不去系统了。 网站找的修复方法均不可行。补救措施&#xff1a;利用DiskGenius.exe&#xff08;要用高版本不然复制的时候就知道了&#xff09; DG1342.rar - 蓝奏云 加载虚拟硬盘 2008x…...

数据结构(算法)

总结&#xff0c;建议看EXCEL的《算法》页签&#xff0c;不然感觉有点乱 备注原理/步骤时间复杂度空间复杂度串的应用模式匹配简单/暴力O(mn) KMP  O(mn) 树的应用树哈夫曼树1、带权路径长度WPL 2、外部排序-最佳归并树1、哈夫曼树的度&#xff0c;只有0和m&#xff08;m叉…...

SpringCloud集成SkyWalking链路追踪并收集日志2

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…...

纯小白蓝桥杯备赛笔记--DAY4(数学数据结构图论)

文章目录 数学质因数分解辗转相除法求最大公约数最小公倍数&#xff1a;快速幂乘法逆元费马小定理 逆元乘法逆元素数判定与埃式筛法朴素素数判定法埃式筛法 图论并查集T3:真题--合根植物DijkstraFloyd 基础算法递归&#xff0c;循环&#xff0c;前缀和&#xff0c;差分STL 数学…...

python 最简单的网页爬虫

import requests url"https://news.ifeng.com/c/8OZc7eV01sM" rrequests.get(url) print(r.status_code) print(r.iter_lines()) # 获取响应的内容 content r.text# 打印网页内容 print(content) # responser.json() # print(response) 爬虫知识讲解&#xff1a; …...

二叉树-数据结构

二叉树-数据结构 二叉树是属性结构的一个重要类型。 如下图二叉树形状 二叉树特征如下&#xff1a; 1.二叉树由 n(n > 0) 个节点组成 2.如果 n 为 0&#xff0c;则为空树 3.如果 n 1&#xff0c;则只有一个节点称为根节点(root) 4.每个节点最多有两个节点&#xff0c;节…...

ansible使用shell模块的环境变量问题

在本机写了一个shell脚本&#xff0c;关于操作mysql的&#xff0c;在本机执行脚本可以正常操作数据库&#xff0c;脚本运行正常。 但是使用ansible ansible -i ./hosts test_teledb -m copy -a "src/etc/ansible/scripts/check.sh dest/tmp"ansible -i ./hosts test…...

ChatGPT论文写作指南:写出引人注目的论文

ChatGPT无限次数:点击直达 ChatGPT论文写作指南&#xff1a;写出引人注目的论文 作为一名有着10年经验的专业CSDN网站原创文章优质创作者&#xff0c;在当今的信息爆炸时代&#xff0c;论文写作的重要性愈发显现。如何能够写出引人注目的论文&#xff0c;吸引读者的眼球并获得…...

ARM64架构栈帧回溯

文章目录 前言一、栈帧简介二、demo演示 前言 请参考&#xff1a;ARM64架构栈帧以及帧指针FP 一、栈帧简介 假设下列函数调用&#xff1a; funb() {func() }funa() {funb() }main() {funa() }main函数&#xff0c;funa函数&#xff0c;funb函数都不是叶子函数&#xff0c;其…...

LangChain:大型语言模型(LLMs)-- 基础知识

1、LangChain的调用大型语言模型模块的介绍 LangChain是一个强大的框架&#xff0c;旨在通过调用大型语言模型&#xff08;LLM&#xff09;来开发各种语言驱动的应用程序。在LangChain中&#xff0c;LLM不仅仅是一个简单的模型调用&#xff0c;而是一个复杂链条中的关键部分。…...

总分410+专业130+国防科技大学831信号与系统考研经验国防科大电子信息与通信工程,真题,大纲,参考书。

好几个学弟催着&#xff0c;总结一下我自己的复习经历&#xff0c;希望大家复习少走弯路&#xff0c;投入的复习正比换回分数。我专业课831信号与系统130&#xff08;感觉比估分要低&#xff0c;后面找Jenny老师讨论了自己拿不准的地方也没有错误&#xff0c;心里最近也这经常回…...

chatgpt Team 4.0共享合租账号的新方式

为了更好地满足工作需求&#xff0c;我订阅了GPT PLUS会员&#xff0c;但我发现&#xff0c;4.0每三小时问答40次经常吃灰&#xff0c;而且每月近200元的费用让我感到有点肉痛。 于是&#xff0c;我开始寻找有没有什么替代品。在逛某论坛的时候&#xff0c;发现了一个共享Team…...

类和对象二

一、运算符重载 为了使自定义类型可以使用加减等运算符&#xff0c;CPP提供了一个功能叫运算符重载。 关键字&#xff1a;operator操作符 运算符重载最好定义在类对象里&#xff0c;这也可以避免访问不到私有成员的问题。 代码演示&#xff1a; 在类里定义之后&#xff0c;…...

GD32 HID键盘矩阵键盘发送数据时,一直发送数据问题处理

这个问题找了两三天,开始并不认为是示例程序的问题,只是感觉是自己代码问题。 这个解决流程大概是: 先调好矩阵键盘=> 调用发送函数。 就是因为调用时,一直发送数据,我也在按键抬起做了操作,始终不行。 最后,发现时示例代码中有个 空闲中断 引起的。 udev->reg…...

小程序地理位置权限申请+uniapp调用uni.getLocation

文章目录 一、小程序地理位置权限申请二、uniapp调用uni.getLocation 一、小程序地理位置权限申请 需要确保小程序类目已经填写 点击左侧导航栏找到最后的“设置”——“基本设置”——“前往填写” 在开发管理——接口设置——地理位置中可以看到&#xff1a; 即可点击想要申…...

后台权限控制及动态路由

需求 后台系统需要能实现不同的用户权限可以看到不同的功能。 用户只能使用他的权限所允许使用的功能。 功能设计 之前在我的SpringSecurity的课程中就介绍过RBAC权限模型。没有学习过的可以去看下 RBAC权限模型 。这里我们就是在RBAC权限模型的基础上去实现这个功能。 表分…...

云计算:Linux 部署 OVS 集群(控制端)实现OpenFlow

目录 一、实验 1.环境 2.Linux 部署 OVS 集群&#xff08;控制端&#xff09; 3.控制端对接服务端OVS网元 4.服务端OVS添加流表 5.服务端删除OVS 二、问题 1. ODL如何查找已安装插件 2.查看流表显示不全 3.如何删除OVS流表 一、实验 1.环境 (1) 主机 表1 宿主机 主…...

使用/api/put保存数据到OpenTSDB,报204错误

错误信息 HttpResponseProxy{HTTP/1.1 204 No Content [Content-Type: application/json; charsetUTF-8, Content-Length: 0]} 错误原因 在OpenTSDB中&#xff0c;使用/api/put保执行写入操作&#xff0c;得到204响应&#xff0c;表示已经成功写入数据库。...

Open3D kmeans聚类(马氏距离,Python版本)

文章目录 一、简介二、算法步骤三、代码实现四、实现效果参考资料一、简介 在诸多的聚类方法中,K-Means聚类方法是属于“基于原型的聚类”(也称为原型聚类)的方法,此类方法均是假设聚类结构能通过一组原型刻画,在现实聚类中极为常用。通常情况下,该类算法会先对原型进行初始…...

Obsidian插件本地化全攻略:从英文界面到中文体验的完整实施路径

Obsidian插件本地化全攻略&#xff1a;从英文界面到中文体验的完整实施路径 【免费下载链接】obsidian-i18n 项目地址: https://gitcode.com/gh_mirrors/ob/obsidian-i18n 在全球化协作与知识管理的场景中&#xff0c;Obsidian插件的英文界面常成为用户高效使用的障碍。…...

Jetson Nano/Xavier NX上,手把手解决Realsense D435i IMU数据丢失的完整配置流程

Jetson Nano/Xavier NX上解决Realsense D435i IMU数据丢失的实战指南 当你兴奋地启动Realsense D435i摄像头&#xff0c;准备获取IMU数据来增强你的机器人项目时&#xff0c;却发现虽然IMU话题存在&#xff0c;但数据流却空空如也——这种挫败感我深有体会。作为在Jetson平台上…...

OpenClaw语音交互方案:Qwen3-32B镜像对接Whisper实时转写

OpenClaw语音交互方案&#xff1a;Qwen3-32B镜像对接Whisper实时转写 1. 为什么需要语音交互方案 作为一个长期与命令行打交道的开发者&#xff0c;我始终在寻找更自然的交互方式。键盘输入固然高效&#xff0c;但在某些场景下——比如双手被占用时调试代码、厨房里边做饭边查…...

零售店长必看:如何用iBeacon+微信小程序打造低成本智能导购(2024最新方案)

零售店长必看&#xff1a;如何用iBeacon微信小程序打造低成本智能导购&#xff08;2024最新方案&#xff09; 走进任何一家现代零售门店&#xff0c;你可能会注意到顾客们不再茫然地寻找商品&#xff0c;而是自然地掏出手机&#xff0c;接收个性化的商品推荐和促销信息。这种无…...

STM32 GPIO模式实战:开漏输出与推挽输出的5个常见应用场景解析

STM32 GPIO模式实战&#xff1a;开漏输出与推挽输出的5个常见应用场景解析 在嵌入式开发中&#xff0c;GPIO&#xff08;通用输入输出&#xff09;是最基础也是最常用的外设之一。STM32系列微控制器提供了多种GPIO模式&#xff0c;其中开漏输出&#xff08;Open-Drain&#xff…...

OpenClaw技能商店:基于nanobot开发并分享自定义模块

OpenClaw技能商店&#xff1a;基于nanobot开发并分享自定义模块 1. 为什么要开发OpenClaw技能 去年夏天&#xff0c;我发现自己每天要花大量时间处理重复性的文件整理工作——下载各种技术文档&#xff0c;按日期和项目分类存储&#xff0c;再手动生成目录索引。当我第三次在…...

Kubernetes 集群管理新选择:Kuboard 图形化界面实战解析

1. 为什么你需要Kuboard这样的Kubernetes图形化管理工具 如果你刚开始接触Kubernetes&#xff0c;可能会被它复杂的命令行操作吓到。记得我第一次使用kubectl时&#xff0c;光是记住各种命令参数就花了两周时间。后来团队规模扩大&#xff0c;管理多个集群时&#xff0c;命令行…...

旧Mac重生指南:用OpenCore Legacy Patcher解锁macOS新版本

旧Mac重生指南&#xff1a;用OpenCore Legacy Patcher解锁macOS新版本 【免费下载链接】OpenCore-Legacy-Patcher 体验与之前一样的macOS 项目地址: https://gitcode.com/GitHub_Trending/op/OpenCore-Legacy-Patcher 你是否有一台性能依然强劲却被苹果官方抛弃的旧Mac&…...

SDMatte高可用集群部署:基于Kubernetes的弹性伸缩方案

SDMatte高可用集群部署&#xff1a;基于Kubernetes的弹性伸缩方案 1. 为什么需要高可用部署方案 电商大促期间&#xff0c;某美妆品牌突然发现他们的AI抠图服务崩溃了——每秒上千张的商品图等待处理&#xff0c;但单机部署的服务早已不堪重负。这种场景在企业级AI应用部署中…...

【AI应用开发】-Agent 思考时间那么长,怎么优化前端的用户体验?

Agent 思考时间那么长&#xff0c;怎么优化前端的用户体验&#xff1f; 文章目录Agent 思考时间那么长&#xff0c;怎么优化前端的用户体验&#xff1f;前言&#xff1a;让等待变成一种享受一、核心策略&#xff1a;透明化 可视化二、实现方案一&#xff1a;Stream 流式输出2.…...