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

包装器 std::function

使用前,包头文件:#include <functional>

std::function 是 C++标准库 中的一个通用函数包装器

它可以储存、复制、调用任何可调用的对象,包括:函数指针成员函数、绑定的成员函数、lambda表达式仿函数等。

1. function 的模板原型
#include <functional>function<Ret(Args...)> 
// Ret 是被调用函数的返回值类型
// Args... 是被调用函数的形参

举一个函数指针的例子讲解:

int fun(int a, int b) {return a + b;
}int main() {function<int(int, int)> func1 = fun; // 此处的 fun 本质是 fun() 的函数指针,与 &fun 无差别// <int(, )> : int 为被调用函数的返回值类型// (int, int) : 为被调用函数的形参return 0;
}
2. function 的几种使用方法
2.1 函数指针

上面的例子已经展示过了。

2.2 成员函数
class Plus
{
public:static int Plusi(int a, int b) // 静态成员函数{return a + b;}double Plusd(double a, double b) // 非静态成员函数{return a + b;}
};int main()
{function<int(int, int)> func2 = &Plus::Plusi;cout << func2(1, 1) << endl;// 非静态成员函数,第一个参数为隐藏的 this 指针function<double(Plus, double, double)> func3 = &Plus::Plusd; cout << func3(Plus(), 1.1, 2.2) << endl;return 0;
}
2.3 lambda 表达式
int main() 
{function<int(int, int)> func4 = [](int a, int b) { return a + b; };return 0;
}
2.4 仿函数
struct Fun {int operator()(int a, int b) {return a + b;}
};int main()
{function<int(int, int)> func5 = Fun();return 0;
}
3. 包装器解决模板效率低下的问题

将下面的代码运行起来,观察 useF() 模板被实例化成了几份?

template<class F, class T>
auto useF(F f, T x) // 实际场景中不建议用 auto 推导返回值类型
{static int count = 0;cout << "count: " << ++count << endl;cout << "count: " << &count << endl;return f(x);
}double f(double x)
{return x / 2;
}struct Fun
{double operator()(double x){return x / 3;}
};int main()
{auto f1 = [](double x) { return x / 4; };cout << useF(f1, 11.11) << endl;cout << useF(f, 11.11) << endl;cout << useF(Fun(), 11.11) << endl;return 0;
}

从运行结果中可以看出, count 始终为 1 且每一个 count 的地址都不相同。事实上,useF() 被实例化成了三份。

我们可以利用包装器解决模板效率低下的问题。

	function<double(double)> func1 = f1;cout << useF(func1, 11.11) << endl << endl;function<double(double)> func2 = f;cout << useF(func2, 11.11) << endl << endl;function<double(double)> func3 = Fun();cout << useF(func2, 11.11) << endl << endl;

为什么通过 std::function 包装后,useF() 只会实例化出一份呢?

不妨通过 typeid 观察 func1、func2、func3 的类型。

http://www.lryc.cn/news/396391.html

相关文章:

  • Java | Leetcode Java题解之第219题存在重复元素II
  • 800 元打造家庭版 SOC 安全运营中心
  • vite项目使用qiankun构建hash路由微前端
  • 通过rpmbuild构建Elasticsearch-7.14.2-search-guard的RPM包
  • js 图片放大镜
  • 数据模型-ER图在数据模型设计中的应用
  • C++ //练习 14.46 你认为应该为Sales_data类定义上面两种类型转换运算符吗?应该把它们声明成explicit的吗?为什么?
  • tensorflow张量生成以及常用函数
  • 如何在 Windows 10 上恢复未保存的 Word 文档
  • Rust入门实战 编写Minecraft启动器#3解析资源配置
  • openFileInput 内部保持的数据如何删除
  • Python编写的俄罗斯方块小游戏
  • 前端直连小票打印机,前端静默打印,js静默打印解决方案
  • python批量读取Excel数据写入word
  • Unity 常用取整方法
  • Apache Seata Mac下的Seata Demo环境搭建
  • 记录|C#安装+HslCommunication安装
  • Android 12系统源码_设备设置(一)Settings介绍
  • 如何查看GD32 Keil和IAR工程的map文件
  • 1Panel安装命令脚本大全,多Linux操作系统版本
  • 校园电动车安全监控和调度系统-计算机毕业设计源码13028
  • 【LLM之Agent】ReAct论文阅读笔记
  • LeetCode 125. 验证回文串
  • IT审计必看!对比旧版,CISA考试改版升级亮点和重点内容是什么?
  • 充电宝哪个牌子公认质量好?哪家充电宝好用?4款口碑好充电宝
  • Python实现图像添加水印的方法
  • MemFire Cloud: 一种全新定义后端即服务的解决方案
  • 职业教育软件测试实验实训室建设应用案例
  • 如何判断一个js对象为数组类型
  • Nacos2.X 配置中心源码分析:客户端如何拉取配置、服务端配置发布客户端监听机制