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

C++——Function原理

众所周知,function可以封装任意类型的可调用对象,功能十分强大,这篇文章主要是想讲解一下function的工作原理。

可调用对象有这么几种类型:仿函数对象、函数指针、lambda表达式... ... 即使这几种可调用对象的参数和返回值类型相同也会被会被判定为不同的类型,毕竟仿函数本质上是类,而函数指针是一个函数指针类型。我们首先要解决的问题就是如何接收不同的类型,答案是模板:

class function { public: template<class T> function(T t) { _t = t; } }

那么问题又来了,function类不知道T这个类型,如何提前定义一个对象(_t)去存储传参进来的可调用对象呢?答案是基类和子类:

class function { public: class Base { public: //虚析构函数保证能够正确调用child1的析构函数,否则调用的是Base的析构函数 virtual ~Base() = default; virtual void revoke() = 0; }; template<class T> class child1 : public Base { T _t; public: child1(T t) : _t(t) {} void revoke() override {_t();} }; template<class T> function(T t) { _base = new child1<T>(t); } ~function() { delete _base; } private: //无论可调用对象是什么类型它永远是Base的子类 Base* _base; };

为了包装器可以像函数一样被调用,我们再重载一个():

class function { public: class Base { public: //虚析构函数保证能够正确调用child1的析构函数,否则调用的是Base的析构函数 virtual ~Base() = default; virtual void revoke() = 0; }; template<class T> class child1 : public Base { T _t; public: child1(T t) : _t(t) {} void revoke() override {_t();} }; template<class T> function(T t) { _base = new child1<T>(t); } ~function() { delete _base; } void operator()() { _base->revoke(); } private: Base* _base; };

到这儿,整个包装器的原理大致就结束了,不过我们可以发现,现在的包装器只能接受无参并且无返回值的可调用对象。这就是为什么定义包装器的时候要传模版类型:

//不能主模板中偏特化,所以先声明主模板 template<class Ret,class... Args> class function; template<class Ret,class... Args> class function<Ret(Args...)>//这是一种偏特化,定义了传模板类型的格式 { public: class Base { public: //虚析构函数保证能够正确调用child1的析构函数,否则调用的是Base的析构函数 virtual ~Base() = default; virtual Ret revoke(Args...) = 0; }; template<class T> class child1 : public Base { T _t; public: child1(T t) : _t(t) {} Ret revoke(Args... args) override {_return _t(args...);} }; template<class T> function(T t) { _base = new child1<T>(t); } ~function() { delete _base; } Ret operator()(Args... args) { return _base->revoke(args...); } private: Base* _base; };
http://www.cnnetsun.cn/news/3602472.html

相关文章:

  • 解决千问text-embedding-v4与GraphRAG的兼容性问题
  • SolidWorks装配体配合关系管理与清理技巧
  • 智慧机场全域动态孪生智能管控系统
  • 认知蒸馏技术:将人类思维转化为AI技能模块
  • 123、OIS光学防抖:陀螺仪标定、音圈马达控制与滚珠式vs悬丝式的机械特性对比
  • 免费又高性能!Cloudflare 临时邮箱助力零成本搭建邮件服务
  • 102、Chipset ISP vs 独立ISP:架构选型与性能权衡
  • Pod 失陷了怎么办?凭据管理系统如何把数据库泄露风险压到零
  • PYTHON+AI LLM DAY ONE HUNDRED AND FOURTEEN
  • Django毕业设计-基于 Django 的高校学生心理健康测评管理系统 大学生心理测评与健康档案管理系统(源码+LW+部署文档+全bao+远程调试+代码讲解等)
  • Django计算机毕设之 基于 Django 的农户自营农产品交易系统乡村振兴农产品直销服务平台设计(完整前后端 代码+说明文档+LW,调试定制等)
  • Gitee Repo Skill 仓库:企业如何集中管理和安全分发 AI Skill
  • 生产计划管理:核心价值、挑战与优化策略
  • Java 锁机制深度解析(系列六):分布式锁
  • Cookie实现Web选项卡状态持久化方案
  • 肿瘤微环境——IFN-γ/IL-10/IL-18/IL-1α/IL-1β/IL-21/IL-6/TNF-α/VEGF-A Panel,重新定义免疫-血管-炎症的联合检测
  • Linux基础命令与开发入门
  • iPad Pro M2运行Win11 Pro的UTM虚拟机完整指南
  • 三星 Galaxy Watch 9 与 Galaxy Watch 8 对比:谁更适合你?
  • 告别噪音与频繁维护:凯尼克静音皮带模组重塑车间
  • ARM Cortex-M时钟门控技术:RCGC/SCGC/DCGC寄存器详解与低功耗实战
  • 2026户外照明商城小程序开发十大平台测评:场景内容、社群与会员怎么选?含零代码SAAS、AI编程、源码定制交付
  • AI系统架构设计:从数据处理到模型部署实战
  • 三星新折叠屏手机首用硅碳电池:小空间大容量,但容量不及OPPO、荣耀!
  • 外贸开发信避坑与选型:一份给业务员的实操清单
  • 托育中心低成本获客神器,凡科全新1折优惠渠道:99做小程序只认餐宝盈,含零代码SAAS、AI编程、源码定制交付
  • 房地产电子沙盘能提高多少转化率?
  • SolidWorks实体合并技巧与焊件处理实战
  • 飞书AI自动化流程实战手册:7类高频场景模板+5个避坑红线,今天部署明天见效
  • 神经网络架构搜索(NAS)技术原理与应用实践