【C++11新特性】function包装器

news2024/10/6 10:28:34

文章目录

  • 1. function包装器
    • 1.1 function包装器介绍
    • 1.2 function包装器对类型的统一
    • 1.3 function包装器的意义

1. function包装器

1.1 function包装器介绍

function包装器是一种函数包装器,也叫做适配器。它可以对可调用对象进行包装,C++中的function本质就是一个类模板。

template <class T> function;
template <class Ret, class... Args>
class Function<Ret(args...)>;
  • Ret :被包装的可调用对象的返回值类型。
  • Args… :被包装的课调用对象的形参类型。

包装示例

function包装器可以对可调用对象进行包装,包括函数指针(函数名)、仿函数(函数对象)、lambda表达式、类的成员函数。

int f(int a, int b)
{
	return a + b;
}

struct Functor
{
public:
	int operator()(int a, int b)
	{
		return a + b;
	}
};

class Plus
{
public:
	static int plusi(int a, int b)
	{
		return a + b;
	}

	double plusd(double a, double b)
	{
		return a + b;
	}
};

int main()
{
	// 1、包装函数指针(函数名)
	function<int(int, int)> func1 = f;
	cout << func1(1, 2) << endl;

	// 2、包装仿函数(函数对象)
	function<int(int, int)> func2 = Functor();
	cout << func2(1, 2) << endl;

	// 3、包装lambda表达式
	function<int(int, int)> func3 = [](int a, int b) {return a + b; };
	cout << func3(1, 2) << endl;

	// 4、包装静态成员函数
	function<int(int, int)> func4 = &Plus::plusi; // &可省略
	cout << func4(1, 2) << endl;

	// 5、包装类的非静态成员函数
	function<double(Plus, double, double)> func5 = &Plus::plusd; // &不可省略
	cout << func5(Plus(), 1.1, 2.2) << endl;

	return 0;
}


  • 包装时指明返回值类型和各形参类型,然后可调用对象赋值给function包装器即可,包装后function对象就可以像普通函数一样使用了。
  • 取静态成员函数的地址可以不用取地址运算符 & ,但取非静态成员函数地址使用 &
  • 包装费静态的成员函数需要注意,非静态成员函数的第一个参数是隐藏this指针,因此在包装时需要指明第一个形参的类型为类的类型。

1.2 function包装器对类型的统一

对于以下函数模板useF:

  • 传入该函数模板的第一个参数可以是任意的,比如函数指针,仿函数,lambda表达式等等。
  • useF中定义了静态变量count,并在每次调用时将count的值和地址进行了打印,可判断多次调用时调用的是否是同一个useF函数。

1.3 function包装器的意义

  • 将可调用对象的类型进行统一,便于我们对其进行统一化管理。
  • 包装后明确了可调用对象的返回值和形参类型,更加方便使用者使用。

在这里插入图片描述
在传入第二个参数类型相同的情况下,如果传入的可调用对象的类型是不同的,那么在编译阶段该函数模板就会被实例化多次。

template <class F, class T>
T useF(F f, T x)
{
	static int count = 0;
	cout << "count: " << ++count << endl;
	cout << "count: " << &count << endl;

	return f(x);
}

double f(double i)
{
	return i / 2;
}

struct Functor
{
	double operator()(double d)
	{
		return d / 3;
	}
};

int main()
{
	// 函数指针
	cout << useF(f, 11.11) << endl;
	// 仿函数
	cout << useF(Functor(), 11.11) << endl;
	// lambda表达式
	cout << useF([](double d)->double {return d / 4; }, 11.11) << endl;

	return 0;
}

运行结果如下:

在这里插入图片描述

由于函数指针、仿函数、lambda表达式是不同的类型,因此useF函数会被实例化出三份,三次调用useF锁打印count的地址也是不同的。

  • 但实际这里根本没有必要实例化出三份useF函数,因为三次调用时传入的可调用对象虽然是不同类型的,但这三个可调用对象的返回值和形参类型都是相同的。
  • 这时就可以用包装器对这三个可调用对象进行包装,然后再用这三个包装后的可调用对象来调用useF函数,这时就只会实例化出一份useF函数。
  • 根本原因就是因为包装后,这三个可调用对象都是相同的function类型,因此最终只会实例化出一份useF函数,该函数的第一个模板参数的类型就是function类型的。

在这里插入图片描述

运行结果如下:

在这里插入图片描述

这时三次调用useF函数所打印count的地址就是相同的,并且count在三次调用后会被累加到3,表示这一个useF函数被调用了三次。

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

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

相关文章

C++【C++学习笔记_Wang】

时间进度C是什么&#xff1f;多态什么是多态&#xff1f;生活中的多态C中的多态 赋值兼容赋值兼容规则实现安全转换 时间进度 Day101 ok Day804 ok Day805 ok C是什么&#xff1f; C大部分包含C语言。 C完全兼容C语言。 C在C语言的基础上添加&#xff1a;封装、继承、多态…

【SpringMVC】JSR 303与interceptor拦截器快速入门

目录 一、JSR303 1、什么是JSR 303&#xff1f; 2、为什么要使用JSR 303&#xff1f; 3、JSR 303常用注解 3.1、常用的JSR 303注解 3.2、Validated与Valid区别 3.2.1、Validated 3.2.2、Valid 3.2.3、区别 4、使用案例 4.1、导入依赖 4.2、配置校验规则 4.3、编写…

vue基础知识九:动态给vue的data添加一个新的属性时会发生什么?怎样解决?

一、直接添加属性的问题 我们从一个例子开始 定义一个p标签&#xff0c;通过v-for指令进行遍历 然后给botton标签绑定点击事件&#xff0c;我们预期点击按钮时&#xff0c;数据新增一个属性&#xff0c;界面也 新增一行 <p v-for"(value,key) in item" :key&q…

QQ 逻辑漏洞可执行文件 漏洞复现

本文由掌控安全学院- wax 投稿 首先拿到QQ的版本&#xff0c;目前可测试版本包括QQ最新版本&#xff0c;TIM最新版本 新创建一个bat文件&#xff08;这个可以随意&#xff0c;上马的也可以&#xff0c;exe也可以&#xff09; &#xff0c;本次测试内容如下首先向你的手机端发一…

一文告诉你什么是 TCP 数据粘包,该如何解决!

粘包问题概述 描述背景 采用TCP协议进行网络数据传送的软件设计中&#xff0c;普遍存在粘包问题。这主要是由于现代操作系统的网络传输机制所产生的。 我们知道&#xff0c;网络通信采用的套接字(socket)技术&#xff0c;其实现实际是由系统内核提供一片连续缓存&#xff08…

如何实现高效客户服务自助?

随着科技的不断发展&#xff0c;越来越多的企业开始意识到提供良好的客户服务对于企业的重要性。而在满足客户需求的同时&#xff0c;高效实现客户服务自助也成为了许多企业关注的焦点。客户服务自助可以帮助企业降低成本、提高效率&#xff0c;同时也能给客户带来更好的体验。…

[每周一更]-(第60期):15种MySQL索引失效场景

背景 工作中都会踩到Mysql数据库不走索引的坑。常见的现象就是&#xff1a;明明在字段上添加了索引&#xff0c;但却并未生效。 另外&#xff0c;无论是面试或是日常&#xff0c;Mysql索引失效的通常情况都应该了解和学习。 为了方便学习和记忆&#xff0c;这篇文件将常见的15种…

人大女王金融硕士项目——当你觉得迷茫的时候,就去学习来充实自己

不要总以为自己的努力会付之东流&#xff0c;不要因为现在的生活或工作还是依旧没有起色&#xff0c;而想太多。继续努力就好&#xff0c;哪怕明天没有惊喜&#xff0c;但最终的你&#xff0c;却在慢慢的变好。对于从业多年的在职人员来说&#xff0c;职业瓶颈期是非常普遍的。…

JDK多版本切换

为什么切换 因为可能不同项目要求JDK的版本不同&#xff0c;比如你上次装的jdk1.8&#xff0c;现在的项目要求JDK9&#xff0c;这时候卸载8再换9有点费劲&#xff0c;而且操作不当可能遇到非常离奇的bug&#xff0c;影响开发进度。如果我们能灵活切换各种jdk版本&#xff0c;将…

揭秘策划行业就业前景怎么样?

策划这个行业总的来说就是&#xff1a;门槛低&#xff0c;上限高&#xff01;&#xff01; 咱们一般说的策划也分很多类型&#xff0c;这里选取身边朋友做的最多的4种类型简单说说。 1、前端品牌策划&#xff0c;转型容易出路广 品牌策划以品牌思维为核心去分析公司的经营发…

蓝桥杯官网练习题(五星填数)

类似题目&#xff1a;https://blog.csdn.net/s44Sc21/article/details/132758982?csdn_share_tail%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22132758982%22%2C%22source%22%3A%22s44Sc21%22%7Dhttps://blog.csdn.net/s44Sc21/article/detail…

【python】代码学习过程问题总结

目录 1. 使用 conda 创建并进入虚拟环境 2. pycharm 选择 interpreter 的时候&#xff0c;在虚拟环境中找不到 python.exe 3.&#xff08;py & python&#xff09;ModuleNotFoundError: No module named XXX 4. AttributeError: module ‘tensorflow‘ has no attribu…

【2023最新B站评论爬虫】用python爬取上千条哔哩哔哩评论

文章目录 一、爬取目标二、展示爬取结果三、爬虫代码四、同步视频五、附完整源码 您好&#xff0c;我是 马哥python说&#xff0c;一枚10年程序猿。 一、爬取目标 之前&#xff0c;我分享过一些B站的爬虫&#xff1a; 【Python爬虫案例】用Python爬取李子柒B站视频数据 【Pyt…

使用TortoiseGit拉取GitLab代码仓库中某一项目的某一分支的代码

使用TortoiseGit拉取GitLab代码仓库中某一项目的某一分支的代码 写在前面&#xff0c;需要补充一点&#xff1a;方式一&#xff1a;使用TortoiseGit图像界面工具&#xff0c;进行直接操作方式二&#xff1a;使用git命令进行操作 写在前面&#xff0c;需要补充一点&#xff1a; …

flask项目请求与响应

项目名&#xff1a; static (静态) js css templates (模板) app.py (运行) web项目 mvc&#xff1a; model 模型 view 视图 controller 控制器 mtv model (模型) templates (模板) --> html view 视图 (python代码) 起控制作用 b/s browser server 浏览器服务器 c…

pcl--第一节 Filters

官方例子在这里&#xff0c;本人使用的pcl1.12.1版本&#xff0c;win11&#xff0c;直接从github下载编译好的版本&#xff0c;使用vs打开cmake&#xff0c;之所以使用cmake&#xff0c;原因是环境配置方便&#xff0c;vs本身配置环境比较麻烦&#xff0c;所以为了方便使用cmak…

FPGA----VCU128的SCUI(上位机软件)无法使用问题

1、第一次使用VCU128&#xff0c;发现很坑&#xff0c;记录一下使用方法。 ①首先需要在购买的包装盒子中找到密匙去官网下载个license ②在Vivado 2019.1版本中将2019.2的板卡数据导入&#xff0c;很奇怪把哈哈哈哈。下面是下载链接 https://github.com/Xilinx/XilinxBoard…

C++中extern的使用

目录 什么是extern&#xff1f;如何使用extern&#xff1f;声明一个全局变量或函数在当前文件中引用其他文件中定义的全局变量或函数 应用场景拓展结论 在C中&#xff0c;extern是一个非常重要的关键字&#xff0c;它用于声明一个变量或函数是在其他文件中定义的。在本文中&…

电子企业MES管理系统有哪些特征

随着科技的飞速发展和全球化的推进&#xff0c;电子行业已成为当今社会至关重要的产业之一。在这个高度竞争的市场环境中&#xff0c;实施一套有效的生产执行管理系统是电子企业提高效率、降低成本、提升品质的重要手段。本文将详细介绍电子企业MES管理系统的特征。 一、定义和…

使用mybatis批量插入数据

最近在做项目的时候&#xff0c;有些明细数据&#xff0c;一条一条的插入太费资源和时间&#xff0c;所以得需要批量插入&#xff0c;今晚闲来无事写个小demo。 新建工程 <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis…