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

news2025/1/21 12:03:22

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对象,它可以像函数一样被调用。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文! 解决镜像法,电轴法在电磁场中的应用

目录 镜像法原理 例题 模型一&#xff1a;无限大导体平面 一些理解 模型二&#xff1a;球面镜像 情况一&#xff1a;球壳接地 同样的几点思考&#xff1a; 情况二&#xff1a;球壳不接地 球壳不接地&#xff0c;但是点电荷放置在内部 镜像法在双层介质中的作用 电轴法…

C++017-C++指针及其应用

文章目录C017-C指针及其应用C指针及其应用CSP-J目标1. 指针1.指针变量的定义、赋值2.指针的引用与运算2. 基于指针的数组访问3. 指针与字符串4. 结构体与指针在练习&#xff1a;总结C017-C指针及其应用 在线练习&#xff1a; http://noi.openjudge.cn/ https://www.luogu.com.c…

设计师都在用的6个免费设计素材网站~

本期给大家推荐几个设计师都在用的素材网站&#xff0c;免费下载&#xff0c;赶紧收藏起来吧~ 1、菜鸟图库 https://www.sucai999.com/?vNTYwNDUx 菜鸟图库是我推荐过很多次的网站&#xff0c;主要是站内素材多&#xff0c;像平面、UI、电商等设计素材都能找到&#xff0c;还…

零售数据可视化|人、货、场、供、财报表分享

有没有零售数据可视化的例子&#xff0c;让大家看看BI零售数据可视化的效果&#xff1f;有&#xff0c;奥威BI零售标准方案提供了数十张BI数据可视化报表&#xff0c;覆盖人、货、场、供、财等核心业务&#xff0c;既可以让大家一次性体验零售数据可视化报表效果&#xff0c;也…

vLive带你走进虚拟直播世界

虚拟直播是什么&#xff1f; 虚拟直播是基于5G实时渲染技术&#xff0c;在绿幕环境下拍摄画面&#xff0c;通过实时抠像、渲染与合成&#xff0c;再推流到直播平台的一种直播技术。尽管这种技术早已被影视工业所采用&#xff0c;但在全民化进程中却是困难重重&#xff0c;面临…

GEE:Gmeans

G-means是一种聚类算法,它是基于K-means算法的改进版本。K-means算法的一个主要缺点是需要事先指定聚类的数量,而G-means算法则可以自动确定聚类的数量。 G-means算法使用了类似于K-means的迭代过程,但在每次迭代时,它会检查每个聚类是否可以继续细分为两个子聚类。这个检…

怎么免费制作logo?logo免费设计在线生成,从此设计不求人

你有没有因为Logo制作而烦恼过&#xff1f;对于很多人来说&#xff0c;logo制作是一项比较大的工程&#xff0c;需要专门的设计师才能完成。但是请人设计费用高还很费时间&#xff0c;还需多次沟通修改。其实&#xff0c;我们可以自己免费制作logo&#xff0c;下面&#xff0c;…

pytorch2.0 起步

参考&#xff1a;https://pytorch.org/get-started/pytorch-2.0/#ask-the-engineers-20-live-qa-series 总览 特性 fastermore pythonicas dynamic as ever torch.compile&#xff0c;部分零件由C迁移到Python,加强torch.compile的新技术有TorchDynamo, AOTAutograd, PrimT…

第十八章 React中的样式模块化处理

在React中组件如何使用本地的样式&#xff0c;而不对其他组件产生影响呢&#xff1f;我们这里需要使用样式的模块化处理&#xff0c;使得组件的样式只在该组件内部起作用。 这里我们通过两个组件应用说明。 定义组件 定义Hello组件与自定义样式 Hello/index.css .title{co…

Win 11 上在VMware 15安装时Ubuntu20.04注意事项(避坑必看)

遇到的问题 https://zhuanlan.zhihu.com/p/141033713 win11不兼容vm–VMware Workstation 与 Device/Credential Guard 不兼容。 https://zhuanlan.zhihu.com/p/428362751 打开控制面板-程序-启用或关闭Windows功能&#xff0c;发现win11没有Hyper-V&#xff0c;别慌&#xf…

算法设计 - 二分法和三分法,洛谷P3382

二分法 二分查找&#xff1a;找目标值位置 二分法是一种适用于特殊场景下的分治算法。 这里的特殊场景指的是&#xff0c;二分法需要作用在一个具有单调性的区间内。 比如&#xff0c;我们熟知的二分查找&#xff0c;就是一种二分法的具体实现&#xff0c;二分查找必须在一…

【云原生】阿里云ACK部署MySQL 数据持久化存储

思路图 一、概述 ACK介绍 阿里云容器服务Kubernetes版(Alibaba Cloud Container Service for Kubernetes,简称容器服务ACK)是全球首批通过Kubernetes一致性认证的服务平台,提供高性能的容器应用管理服务,支持企业级Kubernetes容器化应用的生命周期管理,轻松高效地在云端…

MAE论文阅读《Masked Autoencoders Are Scalable Vision Learners》

文章目录动机方法写作方面参考Paper: https://arxiv.org/pdf/2111.06377.pdf 动机 首先简要介绍下BERT&#xff0c;NLP领域的BERT是基于Transformer架构&#xff0c;并采取无监督预训练的方式去训练模型。它提出的预训练方法在本质上是一种masked autoencoding&#xff0c;也就…

【CSS】定位 ⑤ ( 子元素绝对定位 父元素相对定位 | 代码示例 )

文章目录一、子元素绝对定位 父元素相对定位二、代码示例一、子元素绝对定位 父元素相对定位 绝对定位 要和 带有定位 的 父容器 搭配使用 ; 子元素 使用绝对定位 , 父元素要使用 相对定位 ; 子元素使用 绝对定位 , 在布局中不会保留其位置 , 子元素完全依赖 父容器 的位置 ,…

阿里巴巴春招的后端面经来啦~

操作系统 一个操作系统&#xff0c;我们在衡量它的内存占用的时候&#xff0c;它一般会有哪些内存的部分&#xff1f; 读者答&#xff1a;堆和栈 补充&#xff1a; 这个其实是问你对free命令的理解。 主机的内存做一些清理的动作。你知道这里面会涉及到对哪些内存区域进行操…

大数据任务调度器 —— Azkaban 3.0 进阶应用

文章目录任务依赖任务重试JavaProcess 进程任务提交条件执行自定义条件预定义条件定时执行邮件警告前言&#xff1a;Azkaban 搭建以及基础介绍&#xff0c;查看这篇博客 —— 大数据任务调度器 —— Azkaban 3.0 部署与简单应用 任务依赖 Azkaban 中的任务依赖设置十分简单&…

OpenCV中的相机标定

之前在https://blog.csdn.net/fengbingchun/article/details/130039337 中介绍了相机的内参和外参&#xff0c;这里通过OpenCV中的接口实现对内参和外参的求解。 估计相机参数的过程称为相机标定(camera calibration)。相机标定是使用已知的真实世界模式(例如棋盘)来估计…

从风靡全球到风口,他们是如何做到的?

大家好&#xff0c;我是湖北鑫优尚电子商务。我们是从2019年下半年就注意到了TikTok的风口&#xff0c;并在2020年初&#xff0c;团队就开始投入TikTok的运营及商业变现。从2019年起&#xff0c;围绕TikTok一系列的产品功能迭代和商业模式开放的声音一直不绝于耳&#xff0c;直…

零基础可以学习数据分析吗,有没有好的培训机构推荐?

数据分析从沿海火到了中西部的软件园&#xff0c;从传统互联网企业火到了新经济领域&#xff0c;火到了第一二产业。数字化成为这个时代的标签&#xff0c;而数据也成为了最有价值的资源&#xff0c;更多企业重视数据&#xff1b;因为有了真实数据的支撑&#xff0c;所有的决策…

快速排序(挖坑法 前后指针法 非递归版本)

上一次我们说了快速排序的hoare的版本&#xff0c;但是该版本有很多问题&#xff0c;首先是需要控制很多边界&#xff0c;比较复杂一点 其次就是上一次的快速排序还是有很多的其他问题 我们试着想一下&#xff0c;如果我们用快速排序拍有序数组&#xff0c;那会怎么样&#x…