C++ 包装器function

news2024/11/16 5:50:29

        目录

1、为什么需要包装器?

2、包装器的声明和使用

(1) 声明

(2) 实际应用

(3) 包装器接收类成员函数

3、包装器的绑定:bind函数

(1) 调整参数顺序

(2) 调整参数个数


1、为什么需要包装器?

函数模板可以接收各种不同类型的参数,即便是普通函数、仿函数、lamda表达式也可以接收,但是在实例化的时候,即便形参和返回值完全一样,因为是不同类型,所以需要实例化多份代码。

所以包装器的作用是统一传入的函数对象(前提是不同函数的形参和返回值都要一样),最终只需实例化出一份代码,从而达到提高效率的目的。

// 要传入的函数 / 表达式
int func_add(int x, int y)
{
	return x + y;
}

struct Add {
	int operator()(int x, int y)
	{
		return x + y;
	}
};

auto lamda_add = [](int x, int y) -> int {
	return x + y;
};

// 函数模板
template<class F>
void test_add(F f, int x, int y)
{
	cout << typeid(F).name() << endl;
	f(x, y);
}

2、包装器的声明和使用

(1) 声明

包装器的作用是为了统一传递给模板的函数对象,不同函数的形参和返回值必须一致。

头文件:functional

语法格式:std::function<返回值(形参类型1,形参类型2,...)>  = 函数名 / 函数对象

// 函数func_add,对应的包装器f1
function<int(int, int)> f1 = func_add;
test_add(f1, 10, 20);

// 仿函数Add(),对应的包装器f2
function<int(int, int)> f2 = Add();
test_add(f2, 10, 20);

// lamda表达式lamda_add,对应的包装器f3
function<int(int, int)> f3 = lamda_add;
test_add(f3, 10, 20);

我们会发现不同函数经过包装以后,函数对象的类型都是 function<int(int, int)>,我们再看一下实际调用的结果。

(2) 实际应用

有了包装器,我们可以使用不同的指令来调用不同的函数,以最简答的四则运算为例3

(3) 包装器接收类成员函数

包装器其实也可以接收类的成员函数,包装器接收的是类成员对象的函数地址,使用包装器时需要多传递一个匿名对象,因为实际上是使用匿名对象去调用类成员函数。

class Adds {
public:
	int add(int x, int y) {
		return x + y;
	}
};

int main()
{
    function<int(Adds, int, int)> f4 = &Adds::add;    // 注意这里必须要取地址
    f4(Adds(), 10, 20);
}

结合下面介绍的绑定bind,我们可以在声明的时候就让包装器绑定匿名对象,在实际调用的时候,我们就无需传递匿名对象了。

function<int(int, int)> f4 = bind(&Adds::add, Adds(), placeholders::_1, placeholders::_2);
// f4(10, 20);
test_add(f4, 10, 20);

 

3、包装器的绑定:bind函数

包装器的绑定主要用于调整参数,比如调整顺序、调整参数个数。上面使用包装器接收类的成员函数便是bind的一种应用场景。

既然是调整参数,bind函数是如何获取到包装器对应的函数参数呢?

  • placeholders::_1  表示函数的第一个参数
  • placeholders::_2  表示函数的第二个参数
  • ...
  • 以此类推,bind函数最多可以调整20个参数

(1) 调整参数顺序

首先,我们定义一个简单的lamda表达式,打印传入的内容;

其次,我们使用bind函数调整第一个参数和第二个参数的顺序,再次打印传入的内容。

auto print = [](int x, int y) -> int{
	cout << x << " " << y << endl;
	return 0;
};

cout << "调整参数之前:";
print(10, 20);	// 调整参数之前
function<int(int, int)> func = bind(print, placeholders::_2, placeholders::_1);
cout << "调整参数之后:";
func(10, 20);	// 调整参数之后

 

(2) 调整参数个数

调整参数个数,其实也可以理解为设置缺省值,设置缺省值以后,有些参数就无需重复传递参数

class Adds {
public:
	int add(int x, int y) {
		return x + y;
	}
};

// 正常包装
function<int(Adds, int, int)> f4_1 = &Adds::add;    // 注意这里必须要取地址
f4_1(Adds(), 10, 20);

// 修改参数个数后包装 (将对象设为缺省)
function<int(int, int)> f4_2 = bind(&Adds::add, Adds(), placeholders::_1, placeholders::_2);
f4_2(10, 20);

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

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

相关文章

光流正负值的含义以及如何利用光流进行warping

本文主要介绍光流的形式&#xff0c;光流值的正负代表什么含义&#xff0c;以及如何利用光流进行warping。 1. 光流正负值的含义 光流的概念&#xff1a;光流表示的是从reference frame到target frame&#xff0c;物体的移动。光流的形式&#xff1a;光流的表示也是数字化的。…

镭速-跨国车企数据高速、安全跨境传输解决方案

一、背景及趋势 在新一代信息技术驱动的数字经济时代&#xff0c;数据已然成为新型生产要素&#xff0c;是国家基础性资源和战略性资源。在汽车市场全球化背景下&#xff0c;产品、数据双跨境将成为车企未来常态。数据的价值核心在于流通和应用&#xff0c;但数据也牵涉着竞争…

23.1.30 将TF-A源码移植的过程,整理成自己的笔记

将TF-A源码移植的过程&#xff0c;整理成自己的笔记&#xff0c;上传到CSDN 一、配置TF-A源码 自动探测 自动换行 1.对tf-a源码进行解压 tar xfz tf-a-stm32mp-2.2.r2-r0.tar.gz 打补丁 3.进入tf-a源码目录 $> cd tf-a-stm32mp-2.2.r2 4.打补丁命令 $> for p in ls -1 .…

JavaScript中的Array对象~

初识Array&#xff1a; Array 对象用于在单个的变量中存储多个值 定义&#xff1a; 方式1 //返回的数组为空&#xff0c;length字段为0 var 变量名new Array(); //size是期望的数组元素个数&#xff0c;返回的length字段将被设置为size的值--返回具有指定个数&#xff0c;元…

vue2面试题持续更新。。。

文章目录1、vue 修改数据页面不重新渲染数组/对象的响应式 &#xff0c;vue 里面是怎么处理的&#xff1f;2、生命周期Vue 生命周期都有哪些&#xff1f;父子组件生命周期执行顺序3、watch 和 computed 的区别4、组件通信&#xff08;组件间传值&#xff09;5、$nextTick6、修饰…

postman常用变量总结

一、变量分类环境变量&#xff1a;只在所属环境内使用&#xff1b;全局变量&#xff1a;整个postman中全部接口皆可使用该变量&#xff1b;集合变量&#xff1a;只在设置的集合中可使用&#xff0c;且与环境无关&#xff1b;局部变量数据变量二、环境变量设置方式方式一方式二方…

网络知识详解之:HTTP协议基础

网络知识详解之&#xff1a;HTTP协议基础 计算机网络相关知识体系详解 网络知识详解之&#xff1a;TCP连接原理详解网络知识详解之&#xff1a;HTTP协议基础网络知识详解之&#xff1a;HTTPS通信原理剖析&#xff08;对称、非对称加密、数字签名、数字证书&#xff09;网络知…

第三章.逻辑回归—逻辑回归

第三章.逻辑回归 3.1 逻辑回归&#xff08;Logistic Regression&#xff09; 线性回归以及非线性回归是用来处理回归问题的&#xff0c;而逻辑回归是用来处理分类问题的。 1.应用场景&#xff1a; 1).分类&#xff1a; 垃圾邮件分类预测肿瘤是良性还是恶行预测某人的信用是好…

ITIL知识管理分析及如何实施

什么是知识管理 知识管理是在 IT 服务台内收集、分析、存储和共享知识的过程。它旨在帮助服务台团队在整个使用寿命期间做出正确的决策 通过有效控制和处理信息流来循环和事件解决过程。 ITIL 4将知识管理定义为负责向以下机构提供知识的一个中央流程 所有其他IT 服务管理 &a…

linux / Generic Netlink

一、概述 Generic Netlink 是内核专门为了扩展 netlink 协议簇而设计的“通用netlink协议簇”。由于 netlink 协议最多支持 32 个协议簇&#xff0c;目前 Linux4.1 的内核中已经使用其中 21 个&#xff0c;对于用户需要定制特殊的协议类型略显不够&#xff0c;而且用户还需自行…

SHELL基本知识超级详解

目录 shell基本知识 1&#xff0c;为什么学习和使用Shell编程 2&#xff0c; shell的起源 3&#xff0c;shell的功能 4&#xff0c;shell的分类 5&#xff0c; shell脚本的基本元素 6&#xff0c; shell脚本编写规范 7&#xff0c;shell脚本的执行方式 8&#xff0c; 执…

JavaScript 类的继承

通过原型链的方式继承 通过实例化一个构造函数&#xff0c;使字类的原型指向父类的实例&#xff0c;字类就可以调用到父类的属性和方法 function Parent() {this.parentName 父亲;this.getParentName function () {console.log("parent name is: %s", this.paren…

剑指 Offer 第13天 第14天

目录 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 剑指 Offer 57. 和为s的两个数字 剑指 Offer 58 - I. 翻转单词顺序 剑指 Offer 12. 矩阵中的路径 面试题13. 机器人的运动范围 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 输入一个整数数组&#xff0c;实现一个函…

maven基础-关于什么是maven、如何安装以及在Eclipse中的使用等等

本文是向大家介绍项目管理工具maven的基础使用&#xff0c;它能够实现项目构建打包共享&#xff0c;能够实现自动清理、编译、测试、报告等提高开发效率。一、为什么使用Maven这样的构建工具【why&#xff1f;】二、maven是什么【what&#xff1f;】三、安装maven四、第一个mav…

SpringCloud_02

注意&#xff1a; spring:application:name: userserviceprofiles:active: devcloud:nacos:server-addr: localhost:8848config:file-extension: yaml这里的name如果对应的nacos只有默认的命名空间&#xff0c;就直接写入服务名&#xff0c; 如果有其他的命名空间&#xff0c;…

windows 10使用Pycharm从0到1搭建一个QQ聊天机器人

文章目录选择Python环境安装nb-cli配置Go-cqhttp大工告成&#xff01;选择Python环境 Nonebot2官方说&#xff0c;python版本要大于3.8&#xff0c;推荐大家使用虚拟环境&#xff0c;在Poetry、venv、Conda选择一个自己熟悉的即可。 安装nb-cli pip install -i https://pypi…

2-3-1-1、MySQL相关变种及体系结构

目录与MySQL有关的数据库DrizzleMariaDBPercona ServerPostgre SQLSQLiteMySQL体系结构简介连接池管理工具和服务SQL 接口解析器存储引擎、文件系统连接层Server层&#xff08;SQL处理层&#xff09;缓存缓存弃用的原因存储引擎层MySQL 官方引擎概要InnoDB 存储引擎MylSAM 存储…

Linux常用命令——rexec命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) rexec 运程执行Linux系统下命令 补充说明 rexec命令用于在指定的远程Linux系统主机上执行命令&#xff0c;向远程rexec服务器发出执行命令的请求。 rexec命令通过检查$HOME/.netrc文件&#xff08;包含远程主机…

安装NLTK出现11004和11006错误

出现11404的错误 原因是因为访问github的ip地址出现错误 解决方案&#xff1a; 打开C:->Windows->System32->drivers->etc->host, 打开host文件。 在文件最后添加185.199.108.133 raw.githubusercontent.com&#xff0c;即可解决 可以查看raw.githubusercont…

Sublime Text运行C和C++程序

Sublime Text 是一款当下非常流行的文本编辑器&#xff0c;其功能强大&#xff08;提供有众多的插件&#xff09;、界面简洁、还支持跨平台使用&#xff08;包括 Mac OS X、Linux 和 Windows&#xff09;。 在程序员眼中&#xff0c;Sublime Text 不仅仅是一个文本编辑器&…