You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++26新增std::function_ref与特定delegate的差异对比

C++26新增std::function_ref与特定delegate的差异对比

嘿,咱们今天好好唠唠C++26刚推出的std::function_ref和你提到的这种特定delegate(固定16字节,存类指针+成员函数指针那种)到底有啥不一样,是不是一回事儿——我给你拆解几个核心差异,你一看就明白。

本质定位完全不同

  • std::function_ref本质是个可调用对象的视图,就像你拿个望远镜看远处的东西,望远镜本身不持有那个东西,只是帮你指向它。它不存储任何可调用对象的实体,只是对已经存在的可调用对象做个引用。不管是自由函数、lambda(不管有没有捕获)、成员函数(搭配对象实例)、自定义的函数对象,只要签名能对上,它都能绑定。
  • 你说的这种16字节delegate是个特定场景的可调用信息容器,它的核心是存储了调用所需的两个指针:要么是类对象的指针+成员函数指针,要么是自由函数的指针+空指针。它是把调用的必要信息存起来了,不过能力比较专一,主要针对成员函数+对象的组合场景。

适用范围天差地别

  • std::function_ref的适配性拉满:无捕获lambda、带捕获的lambda、全局函数、静态成员函数、绑定了对象的成员函数、甚至你自己写的重载了operator()的函数对象,只要签名匹配,统统能搞定。而且它不需要拷贝这些可调用对象,只是引用它们,只要原对象活着,它就能正常用。
  • 这种16字节delegate就有点“偏科”了:它只能处理能用两个指针搞定的可调用场景。比如成员函数+对象,或者自由函数。但碰到带捕获的lambda(本质是带成员变量的匿名类,捕获的数据没法塞进两个指针里)、或者自定义的大尺寸函数对象,它就束手无策了。

内存与生命周期特性不同

  • std::function_ref是轻量级的,大小通常是1到2个指针(具体看实现),而且完全不持有内存——它不会做堆分配,也不会拷贝原可调用对象。但它有个致命的依赖:必须保证原可调用对象的生命周期比它长,要是原对象没了,std::function_ref就成了“悬垂引用”,调用它就是未定义行为。比如你绑定了一个局部的带捕获lambda,函数执行完lambda销毁了,再用std::function_ref调用直接炸锅。
  • 这种delegate固定占16字节(64位系统下两个8字节指针),它存储了调用所需的指针,所以本身是独立的,但同样依赖指针指向的内容的生命周期:如果是绑定了对象实例,那对象没了调用也会出问题;但如果是绑定自由函数或者静态成员函数,那它的生命周期就和程序一样长,因为函数地址是全局有效的。

类型擦除的能力不同

  • std::function_ref的类型擦除是通用的:它擦除了可调用对象的具体类型,只保留了函数签名信息。不管你给它什么花里胡哨的可调用对象,只要能以目标签名调用,它都能处理。
  • 这种delegate的类型擦除非常有限:它只擦除了具体的类类型和成员函数类型,只能处理“对象+成员函数”或者“自由函数”这两种固定模式,没法应对更复杂的可调用对象。

总结一句:这俩完全不是一回事儿,std::function_ref是通用的、无所有权的可调用对象视图,而你说的delegate是针对特定场景的轻量级可调用包装,能力范围窄多了。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 12:53:15