C++ 23 实用工具(二)绑定工具

C++ 23 实用工具(二)绑定工具

267404

Adaptors for Functions

std::bindstd::bind_frontstd::bind_backstd::function这四个函数非常适合一起使用。

其中,std::bindstd::bind_frontstd::bind_back可以让您即时创建新的函数对象,而std::function则可以将这些临时的函数对象绑定到变量上。

然而,在C++中,这四个函数大多数情况下都是多余的。首先,您可以使用lambda表达式代替std::bindstd::bind_frontstd::bind_back;其次,您通常可以使用自动类型推导的auto关键字代替std::function

因此,尽管在某些特定场景下,这些函数仍然是有用的,但在大多数情况下,它们并不是必须的。

std::bind

#include <functional>
#include <iostream>

using namespace std::placeholders;

double divMe(double a, double b) { return a / b; };

int main()
{
	std::function<double(double, double)> myDiv1 = std::bind(divMe, _1, _2);
	std::function<double(double)> myDiv2 = std::bind(divMe, 2000, _1);
	std::function<double(double)> myDiv3 = std::bind_front(divMe, 2000);
	std::function<double(double)> myDiv4 = std::bind_back(divMe, 10);

	std::cout << "myDiv1(1000, 5) = " << myDiv1(1000, 5) << std::endl; // 200
	std::cout << "myDiv2(10) = " << myDiv2(10) << std::endl; // 200
	std::cout << "myDiv3(5) = " << myDiv3(5) << std::endl; // 400
	std::cout << "myDiv4(2000) = " << myDiv4(2000) << std::endl; // 200
	return 0;
}

借助std::bind,您可以以多种方式创建函数对象:

  • 将参数绑定到任意位置
  • 改变参数的顺序
  • 引入占位符
  • 部分求值函数

通过std::bind创建的新函数对象可以被调用、用于STL算法或者存储在std::function中。

std::bind_front (C++20)

std::bind_front函数可以从可调用对象创建可调用包装器。调用std::bind_front(func, arg...)会将所有参数arg绑定到func的前面,并返回一个可调用包装器。

std::bind_back (C++23)

std::bind_back函数可以从可调用对象创建可调用包装器。调用std::bind_back(func, arg...)会将所有参数arg绑定到func的后面,并返回一个可调用包装器。

std::function

std::function函数可以将任意可调用对象存储到变量中,它是一个多态的函数包装器。可调用对象可以是lambda函数、函数对象或者函数。如果需要显式指定可调用对象的类型,则必须使用std::function,它无法被auto关键字替换。

std::tie 和 std::ignore

std::tie函数可以创建引用变量的元组。当您需要同时返回多个值时,可以使用std::tie函数将这些值打包成一个元组返回,并通过引用将元组的内容解包到变量中。

例如,假设您有一个返回两个值的函数foo(),您可以使用std::tie函数将这两个值打包成一个元组返回,并通过引用将元组的内容解包到两个变量中:

int x, y;
std::tie(x, y) = foo();

如果您不需要元组中的某个元素,则可以使用std::ignore函数将其忽略。例如,假设您只需要元组中的第一个值,可以将第二个值用std::ignore函数忽略:

int x, y;
std::tie(x, std::ignore) = foo();

这样,foo()返回的元组中的第二个值将被忽略。

#include <tuple>
#include <iostream>

using namespace std;

int main()
{
	int first = 1;
	int second = 2;
	int third = 3;
	int fourth = 4;
	cout << first << " " << second << " " << third << " " << fourth << endl; // 1 2 3 4

	auto tup = std::tie(first, second, third, fourth) = std::make_tuple(101, 102, 103, 104); // 绑定元组并赋值
	cout << get<0>(tup) << " " << get<1>(tup) << " " << get<2>(tup) << " " << get<3>(tup) << endl; // 101 102 103 104
	cout << first << " " << second << " " << third << " " << fourth << endl; // 101 102 103 104

	first = 201;
	get<1>(tup) = 202;
	cout << get<0>(tup) << " " << get<1>(tup) << " " << get<2>(tup) << " " << get<3>(tup) << endl; // 201 202 103 104
	cout << first << " " << second << " " << third << " " << fourth << endl; // 201 202 103 104

	int a, b;
	tie(std::ignore, a, std::ignore, b) = tup;
	cout << a << " " << b << endl; // 202 104

	return 0;
}

Reference Wrappers

Reference Wrappers是一个定义在头文件中的可复制构造和可复制赋值的包装器,用于类型&的对象。它具有像引用一样的行为,但可以被复制。与传统引用不同,std::reference_wrapper对象支持两个附加用例:

  • 您可以在标准模板库的容器中使用它们。例如:std::vector<std::reference_wrapper<int>> myIntRefVector
  • 您可以复制具有std::reference_wrapper对象的类的实例。通常情况下,这对于引用是不可能的。

get成员函数允许访问引用:myInt.get()。您可以使用引用包装器来封装和调用可调用对象。

Reference Wrappers在处理需要使用引用的情况时非常有用,同时也允许在STL容器中存储引用类型的对象,这是传统引用无法做到的。因此,它是C++中一个非常方便的工具。

#include <functional>
#include <iostream>

void foo()
{
	std::cout << "被调用了" << '\n';
}

typedef void callableUnit();
std::reference_wrapper<callableUnit> refWrap(foo);

int main()
{
	refWrap(); // 输出 "被调用了"
	return 0;
}

这段代码定义了一个名为foo的函数,它没有参数和返回值。接下来,我们定义了一个名为callableUnit的函数类型别名,它代表没有参数和返回值的函数类型。然后,我们使用std::reference_wrapperfoo包装到refWrap中。

main函数中,我们直接调用refWrap(),这实际上会调用foo()函数并输出"被调用了"。由于refWrap是一个std::reference_wrapper对象,它可以像函数一样被调用。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

protobuf编码格式解析

示例 假如定义一个如下的protobuf类型 message Person {required string user_name 1;optional int64 favorite_number 2;repeated string interests 3; }将其赋值为: user_name : "Martin" favorite_number : 1337 interests:"daydrea…

(PCB系列三)AD六层板布线经验累积

目录 1、布局&#xff1a; 2、创建电源类PWR 3、高速部分可以加屏蔽罩&#xff0c; 4、EMMC和NANDFLASH采取兼容放置&#xff08;创建联合&#xff09; 5、HDMI设计 6、就近原则摆放 7、AV端口 8、模拟信号&#xff08;1字型或L型走线&#xff09; 9、WIFI模块 10、局…

【精华】表格结构识别模型研究进展

表格结构识别模型研究进展 合合信息&#xff1a;表格识别与内容提炼技术理解及研发趋势 OCR之表格结构识别综述 表格识别技术综述 用于表检测和结构识别的深度学习&#xff1a;综述 &#xff08;1&#xff09;PP-Structure 速度提升11倍&#xff0c;一键PDF转Word PP-St…

【软考备战·希赛网每日一练】2023年4月12日

文章目录 一、今日成绩二、错题总结第一题 三、知识查缺 题目及解析来源&#xff1a;2023年04月12日软件设计师每日一练 一、今日成绩 二、错题总结 第一题 解析&#xff1a; 依据题目画出PERT图如下&#xff1a; 关键路径长度&#xff08;从起点到终点的路径中最长的一条&…

递归算法_字符串反转_20230412

递归算法-字符串反转 前言 递归算法对解决重复的子问题非常有效&#xff0c;字符串反转也可以用递归算法加以解决&#xff0c;递归算法设计的关键是建立子问题和原问题之间的相关性&#xff0c;同时需要确立递归退出的条件&#xff1b;如果递归退出的条件无法确定&#xff0c…

说过的话就一定要办到 - redo日志

一、什么是redo日志&#xff1f; 如果我们只在内存的 Buffer Pool 中修改了页面&#xff0c;假设在事务提交后突然发生了某个故障&#xff0c;导致内存中的数据都失效了&#xff0c;那么这个已经提交了的事务对数据库中所做的更改也就跟着丢失了&#xff0c;这会导致事务会失去…

4.基于多目标粒子群算法冷热电联供综合能源系统运行优化

4.基于多目标粒子群算法冷热电联供综合能源系统运行优化《文章复现》 相关资源代码&#xff1a;基于多目标粒子群算法冷热电联供综合能源系统运行优化 基于多目标算法的冷热电联供型综合能源系统运行优化 考虑用户舒适度的冷热电多能互补综合能源系统优化调度 仿真平台:matl…

Segment Anything论文翻译,SAM模型,SAM论文,SAM论文翻译;一个用于图像分割的新任务、模型和数据集;SA-1B数据集

【论文翻译】- Segment Anything / Model / SAM论文 论文链接&#xff1a; https://arxiv.org/pdf/2304.02643.pdfhttps://ai.facebook.com/research/publications/segment-anything/ 代码连接&#xff1a;https://github.com/facebookresearch/segment-anything 论文翻译&…

性能测试,python 内存分析工具 -memray

Memray是一个由彭博社开发的、开源内存剖析器&#xff1b;开源一个多月&#xff0c;已经收获了超8.4k的star&#xff0c;是名副其实的明星项目。今天我们就给大家来推荐这款python内存分析神器。 Memray可以跟踪python代码、本机扩展模块和python解释器本身中内存分配&#xf…

VR全景展示,VR全景平台,助理全景展示新模式

引言&#xff1a; VR全景展示是一种新型的展示方式&#xff0c;它利用虚拟现实技术和全景拍摄技术&#xff0c;使参观者可以身临其境地进入虚拟展览空间。这种展示方式不仅能够提供更加沉浸式的参观体验&#xff0c;还可以解决传统展览所面临的时间和地域限制等问题。 VR全景展…

测试工具之JMH详解

文章目录 1 JMH1.1 引言1.2 简介1.3 DEMO演示1.3.1 测试项目构建1.3.2 编写性能测试1.3.3 执行测试1.3.4 报告结果 1.4 注解介绍1.4.1 BenchmarkMode1.4.2 Warmup1.4.3 Measurement1.4.4 Threads1.4.5 Fork1.4.6 OutputTimeUnit1.4.7 Benchmark1.4.8 Param1.4.9 Setup1.4.10 Te…

leetcode 812. 最大三角形面积

题目 给你一个由 X-Y 平面上的点组成的数组 points &#xff0c;其中 points[i] [xi, yi] 。从其中取任意三个不同的点组成三角形&#xff0c;返回能组成的最大三角形的面积。与真实值误差在 10-5 内的答案将会视为正确答案。 示例 1&#xff1a; 输入&#xff1a;points [[…

ActiveReportsJS 4.0 FIX ActiveReportsJS 4.0 Crack

JavaScript 报告工具是一组用于数据整合和可视化的 Web 组件。ActiveReportsJS 是前端开发人员用来在 Web 应用程序中嵌入报告的解决方案。报表设计器和查看器组件、强大的数据可视化器和丰富的 API 等主要功能使 ActiveReportsJS 成为行业领导者。 JavaScript 报告引擎 利用强…

Spark SQL join操作详解

一、 数据准备 本文主要介绍 Spark SQL 的多表连接&#xff0c;需要预先准备测试数据。分别创建员工和部门的 Datafame&#xff0c;并注册为临时视图&#xff0c;代码如下&#xff1a; val spark SparkSession.builder().appName("aggregations").master("lo…

Python进阶内容--迭代器和生成器

什么是迭代器 在 Python 中&#xff0c;迭代器&#xff08;Iterator&#xff09;是一个访问集合元素的对象&#xff0c;它能够实现遍历集合的所有元素&#xff0c;而无需了解集合底层结构和细节。Python 中所有可迭代的对象&#xff08;如 列表、元组、字符串、字典、集合等&a…

leetcodeTmp

文章目录 39. 组合总和33. 搜索旋转排序数组153. 寻找旋转排序数组中的最小值49. 字母异位词分组53. 最大子数组和55. 跳跃游戏56. 合并区间62. 不同路径 39. 组合总和 39. 组合总和 DFS排列&#xff1a;每个元素可选0次&#xff0c;1次以及多次 public List<List<Int…

元宇宙:虚拟仿真技术的全面提升

在当今数字化的世界中&#xff0c;我们经常听到虚拟现实、增强现实、混合现实等技术的名词&#xff0c;这些技术的应用越来越成熟。其中&#xff0c;虚拟仿真技术是一种通过计算机技术来模拟实际场景和对象的过程&#xff0c;它为我们提供了更多的可能性。而最近备受瞩目的元宇…

加密的本质:数学的不对称性

文章目录 引言I 预备知识1.1 加密和授权1.2 非对称的特性II 椭圆曲线加密的方法2.1 椭圆曲线2.2 椭圆曲线的性质引言 不对称有时却自有其妙处与美感,比如黄金分割就是不对称的。 可以通过加密和授权,兼顾保护信息不外泄,而且某些得到授权的人还能使用信息。 I 预备知识 …

亚马逊云科技为全球的可持续发展进程做出贡献

可持续发展是一个涉及经济、环境和社会三个方面的复杂问题。经济发展必须在保护环境和社会公正的前提下进行&#xff0c;这样才能实现真正的可持续发展。为了实现这一目标&#xff0c;人们需要借助技术手段&#xff0c;更好地理解和解决环境和社会问题。 亚马逊云科技是全球领…

(大数据开发随笔9)Hadoop 3.3.x分布式环境部署——全分布式模式

索引 完全分布式模式守护进程布局集群搭建准备总纲配置文件格式化集群启动集群 集群控制命令集群启停进程查看启动日志查看集群常见问题 案例演示&#xff1a;WordCount 完全分布式模式 分布式文件系统中&#xff0c;HDFS相关的守护进程也分布在不同的机器上&#xff0c;如&am…