std::function的讲解与实战

C++回调机制:从函数指针到std::function的全面解析与实践 在C++编程中,回调机制是实现事件驱动、异步处理和算法定制化的核心技术。其原理是通过传递可调用对象作为参数,实现控制反转,让框架代码能够在特定时机调用用户自定义的逻辑。这一技术价值在于解耦调用方与实现方,提升代码的模块化与复用性。在异步I/O、GUI事件处理、策略模式等应用场景中,回调机制尤为关键。传统的C风格函数指针虽然基础,但无法直接指向成员函数或lambda表达式,限制了其表达能力。C++11引入的std::function作为可调用对象的通用包装器,通过类型擦除技术,能够统一封装普通函数、成员函数、 阅读详情

一、C语言中的函数指针

先看一个函数指针的例子 test_fun.cpp:

#include<iostream>

//定义函数指针
typedef int (*func)();

using namespace std;

int test1(){
    cout<<"hello, test1"<<endl;
    return 0;
}

int test2(){
    cout<<"hello, test2"<<endl;
    return 0;
}

int main(int argc, char * argv[]){
    func fp = test1;
    fp();

    fp = test2;
    fp();

    return 0;
}

执行结果如下:

 二、std::function的作用

其实std::function的作用跟上面的函数指针类似。

但std::function的作用比函数指针更强大,应用场景更多。std::function是一个可调用的对象包装器,满足下列条件之一的是可调用对象:

(1)函数指针
(2)具有operator()成员函数的类对象(传说中的仿函数),lambda表达式
(3)可被转换为函数指针的类对象
(4)类成员(函数)指针
(5)bind表达式或其它函数对象

在实际编程时,主要有以下场景:

(1)绑定一个函数(普通函数或者静态函数)
(2)实现回调函数
(3)作为函数入参

三、几个例子

1、绑定一个函数

#include <iostream>
#include <functional>

using namespace std;

int test1(){
    cout<<"hello, test1"<<endl;
    return 0;
}

int main(int argc, char * argv[]){
    std::function<int(void)> fr_test1 = test1;
	fr_test1();

    return 0;
}

2、作为回调函数

#include <iostream>
#include <functional>

using namespace std;

class A{
    function<void()> callback;

public:
    A(){};
	
    A(const function<void()>& f) : callback(f) {};
	
	void notify(void){
		callback();
	}
	
	void init(const function<void()>& f){
	    callback = f;
	}
};

class Foo {
public:
    // Foo foo;
	// foo(); //此时会执行operator()方法
    void operator()(void) {
        cout << __FUNCTION__ << endl;
    }
};

void test(){
    cout << "test()" << endl;;
}

int main(void)
{
  Foo foo;
  
  A aa(foo);
  aa.notify();
  
  A bb;
  bb.init(test);
  bb.notify();
}

3、作为函数入参

#include <iostream>
#include <functional>

using namespace std;

void call_when_even(int x, const std::function<void(int)>& f) {
    if (!(x & 1)) {
        f(x);
    }
}

void output(int x) {
    cout << x << " ";
}

int main(void){
    for (int i = 0; i < 10; ++i) {
        call_when_even(i, output);
    }
	
	cout<<endl;
	
    return 0;
}

参考:

(1)深入浅出C++的function

(2)c++11新特性之std::function和lambda表达式

现代C++核心特性实战:可变参数模板、智能指针与回调函数深度整合 在C++编程中,泛型编程和资源管理是构建健壮、高效软件系统的基石。泛型编程通过模板技术实现代码复用和类型安全,而资源管理则确保内存等系统资源得到正确释放,避免泄漏。这些原理催生了现代C++中的关键技术,如可变参数模板,它允许函数和类模板接受任意数量和类型的参数,极大地提升了代码的灵活性和泛化能力;以及智能指针,它通过RAII(资源获取即初始化)机制自动化内存管理,显著提升了代码的安全性。这些技术的核心价值在于,它们能够帮助开发者编写出更安全、更高效、更易于维护的代码,尤其适用于开发库、框架和高性能中间件。在 阅读详情

相关推荐

C/C++回调函数:从函数指针到Lambda的异步编程核心

在软件工程中,解耦与异步处理是提升系统模块化和响应能力的关键设计思想。其核心原理在于将特定行为的定义与执行时机分离,通过将可执行代码单元作为参数传递,实现控制反转。这一技术价值在于构建出灵活、可扩展的架构,广泛应用于事件驱动系统、图形界面消息循环、网络I/O以及算法策略定制等场景。函数指针作为C语言实现该思想的底层机制,提供了基础的灵活性。而在现代C++中,std::function与Lambda表达式极大地增强了回调的安全性与表达能力,成为实现异步操作和事件通知的基石。本文通过模拟下载管理器等实例,深入探

weixin_30824599的博客 475

函数指针与 std::function 简介

函数指针与std::function简介 ​ 在c/c++实际编程中,使用函数指针/function对象有时候可以让我们的代码更加简洁条理,尤其存在对同一对象多种不同的处理方案时,使用函数指针/function对象结合std::map等数据结构,会有效减少代码中臃肿的if...else语句。 ​ 一般情况下,代码中的可调用对象可大致概括为如下几种形式,另外仍有诸如仿函数对象等存在,其有自身调用特征的特殊性,但是又符合一般调用的法则,所以下文只针对个人常见常用的几种可调用对象。 void ordinary

degawong的博客 2207

C++函数对象与Lambda表达式:从基础原理到STL实战应用

在C++编程中,可调用对象是实现灵活行为抽象的核心概念。函数对象通过重载operator()实现,本质上是具有状态的类实例,为STL算法提供了可定制的操作单元。其技术价值在于将行为封装为对象,支持状态保持和值语义传递,广泛应用于排序、查找、变换等算法场景。随着C++11引入Lambda表达式,这一机制得到极大简化,开发者可以就地定义匿名函数对象,通过捕获列表灵活访问外部变量。本文聚焦函数对象与Lambda的核心机制,深入解析捕获列表、mutable关键字、性能优化等关键点,并结合STL算法展示其在排序、累积

weixin_33701564的博客 336

c++ std::funciona代替函数指针——结合std::bind

std::function是函数模板类(是一个类)。包含在#include 中。以前没有这个类的时候,我们在想定义一个回调函数指针,非常的麻烦。typedef void(*ptr)(int,int)// 这里的ptr就是一个函数指针而使用了std::function这个类的时候,我们可以这样使用,来替换函数指针。例如std::function 是一种通用、多态的函数封装。它的实例能存储、复制及调用任何可调用 (Callable) 目标——

hml111666的博客 2808

C++ Lambda表达式与函数模板:从回调到泛型编程的实战指南

在C++编程中,函数指针和函数对象是处理回调、算法定制等场景的传统方式,但代码往往分散且维护困难。Lambda表达式作为一种匿名函数对象,通过就地定义的方式解决了这一问题,让代码逻辑更紧凑。其核心原理在于捕获列表机制,允许Lambda访问外部变量,并通过值捕获或引用捕获控制变量生命周期。在技术价值上,Lambda不仅提升了代码可读性,还能与STL算法无缝结合,实现高效的泛型编程。函数模板则进一步扩展了这种能力,通过类型参数化支持通用算法设计。在实际应用场景中,Lambda常作为谓词用于std::sort、s

weixin_34314962的博客 797

C++中std::function详解和实战示例

场景描述回调机制可存储传入的回调函数(例如事件触发、完成通知)异步任务调度用作任务队列中的任务封装策略模式在运行时动态替换策略行为(如算法接口)通用函数接口支持用户传入任意处理逻辑,提高系统模块化应用用法类型线程池封装任意任务事件系统注册/触发事件响应回调插件接口动态注册功能实现或更复杂结构。

qq_36812406的博客 2466

std::function、std::bind、函数指针的使用

先说函数指针: 函数指针区别于指针函数,指针函数,就是一个普通的函数,只是返回值是指针;函数指针,我们可以把一个函数的地址通过指针来存放,这个指针就是函数指针变量,简称函数指针。 int * func(int a,int b) //指针函数,定义了一个具有两个int型参数的函数,返回值是int型的指针。 int(*func)(int a,int b) //函数指针,定义了一个指...

Bruce 4060

第2.8章 机器人C++学习实战总结(九):吃透C++函数-SLAM/自动驾驶编程的“核心引擎”,从基础到项目实战全攻略

在 C++ 的世界里,函数就像是一个个具备特定功能的 “小机器”,而函数的定义则是打造这台 “小机器” 的详细蓝图。函数定义主要由以下几个关键部分组成:返回值类型,它决定了函数执行完毕后会给调用者返回什么样的数据;函数名,如同人的名字一样,方便我们在程序中调用这个函数;参数列表,这里存放着函数运行时所需的各种输入数据;还有函数体,这是函数的核心部分,里面包含了实现具体功能的一系列代码。例如,下面这个简单的函数定义:在这个例子中,int是返回值类型,表示函数会返回一个整数;add是函数名;

行知SLAM 285

C++笔记-使用std::funcional代替函数指针

目录 基本概念 代码与实例 基本概念 在C++中有个functional的头文件中有一个functional,可以代替函数指针!具体代码如下! 代码与实例 程序运行截图如下: 源码如下: #include <iostream> #include <functional> using namespace std; void func(voi...

IT1995的博客 6486

Flotherm XT新手必看:5分钟搞定自然对流热仿真(附案例文件)

本文为Flotherm XT新手提供了自然对流热仿真的快速入门指南,通过详细的步骤解析和实用技巧,帮助用户在5分钟内完成从建模到后处理的全流程。重点介绍了环境设置、几何建模、材料属性、网格划分等关键环节,并附有案例文件供参考学习,助力工程师快速掌握热仿真技术。

weixin_30839881的博客 621

基于强化学习框架的交易策略学习过程

每个状态s∈S 是一个由六个微观结构特征构成的向量,这些特征反映了当前市场的订单簿状态和近期交易行为。

xu624735206的博客 1110

std::function

本文深入解析了C++11中的std::function工具,它是Linux C++后端开发中实现回调机制的核心组件。文章首先介绍了std::function的基础用法,包括包装普通函数、仿函数、lambda和类成员函数的方法,并对比了其与函数指针的差异。其次详细剖析了std::function的类型擦除实现原理,以及它与std::bind的配合使用。接着通过三个实战案例(事件驱动架构、线程池任务队列和策略模式)展示了std::function在工业级开发中的应用。最后总结了常见陷阱和优化技巧,强调在灵活性与

m0_62807361的博客 930

hcaptcha无感验证码逆向实战:从接口分析到环境补全

本文详细解析了hcaptcha无感验证码的逆向实战过程。通过分析核心接口与加密逻辑,重点介绍了采用环境补全策略来模拟真实浏览器环境,从而绕过验证码检测。文章提供了从接口抓包、剖析hsw.js加密核心到使用Node.js搭建模拟环境的完整步骤,为自动化操作提供了一种稳健的解决方案。

weixin_29324401的博客 1152

C++智能指针与STL高阶应用:从原理到实战的进阶指南

在C++编程中,内存管理和数据结构的有效运用是提升代码质量与性能的核心。智能指针通过自动化资源管理,解决了传统手动内存分配可能引发的内存泄漏问题,其原理基于引用计数与所有权语义,为复杂系统提供了安全的基础。结合STL容器与算法,开发者能够构建高效、可维护的应用程序,尤其在并发编程和回调机制中展现技术价值。本文聚焦于shared_ptr的定制删除器与内存池集成、weak_ptr在缓存设计中的应用,以及std::function与STL算法的高阶技巧,通过实战案例如异步任务队列,帮助开发者深入理解这些工具在工程

keke1314520的博客 357

AI影像组学在结直肠癌诊疗中的应用:从特征提取到临床决策

影像组学通过高通量计算从医学影像中提取定量特征,揭示肿瘤内部的微观生物学行为,这些特征反映了纹理异质性、形状不规则度等影像表型。其核心原理在于将图像数据转化为可分析的数字特征,结合机器学习算法进行模式识别,从而实现对疾病状态的精准预测。这一技术的价值在于能够无创、定量地评估肿瘤特性,为精准医疗提供关键支持。在临床实践中,AI驱动的影像组学模型广泛应用于结直肠癌的诊疗全链条,包括肿瘤良恶性鉴别、基因突变预测、治疗反应评估和预后分析等场景。通过整合影像组学特征与临床数据,可以构建预测模型,辅助医生进行更准确的诊

weixin_28295799的博客 409

YOLO26优化:原创自研 | 自研独家创新DSAM注意力 ,基于BiLevelRoutingAttention注意力升级

提出新颖的注意力DSAM(Deformable Bi-level SpatialAttention Module),创新度极佳,适合科研创新,效果秒杀CBAM,Channel Attention+Spartial Attention升级为新颖的Deformable Bi-level Attention+Spartial Attention

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 365

拒绝死记硬背!一文快速上手Lambda匿名函数与 std::function

本文采用通俗易懂的比喻与字符画图解,系统化拆解 C++ 中 Lambda 表达式与 std::function 的核心机制。从基础语法、捕获列表(值捕获与引用捕获)到 STL 实战,并深度剖析 C++11 至 C++23 递归 Lambda 的演进与底层原理,助你零基础彻底吃透现代 C++ 核心知识点。

kumaxi的博客 637

零基础DSP实战TMS320F28035:第九节,ADC比较器&EPWM

ADC比较器框图如下所示:-电压-----------------------------输出-电压A>电压B------------------ 1-电压A

sinat_30943509的博客 2535

C++STL教程:函数对象与Lambda表达式

函数对象(Functor)是重载了operator()的类对象,可以像函数一样调用。与普通函数相比,它可以保存状态。// 函数对象:重载 operator()private:int base;// 保存状态public:// 8(像函数一样调用)// 13return 0;

CJLU_WSJ的博客 227

无迹卡尔曼滤波 (UKF, Unscented Kalman Filter) 算法详解及案例分析

无迹卡尔曼滤波是一种用于估计非线性系统状态的递归算法。其目标是通过结合系统模型和观测数据,估计系统的最优状态。

闲人编程的博客 2628

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

C++11-17 新特性详解

摘要:现代C++核心特性精要 本文系统介绍了C++11至C++17版本的核心语言特性,包括: Lambda表达式语法与捕获规则 auto类型推导与decltype用法 移动语义、完美转发及智能指针实践 std::function与std::bind函数包装技术 emplace操作与优先队列优化 thread_local线程局部存储 高效位运算技巧 常见编程陷阱与解决方案 重点强调了现代C++在内存管理、类型推导、多线程支持等方面的改进,提供了大量可直接应用于实际开发的代码示例和优化建议。特别对智能指针的循环

qq_23310275的博客 414

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

C++可变参数模板与函数包装器:从语法到实战的完整指南

在C++编程中,泛型编程和代码复用是提升工程效率的核心技术。通过模板元编程,开发者可以在编译期实现类型安全的抽象,这是现代C++库设计的基石。可变参数模板作为C++11引入的关键特性,其技术价值在于允许函数和类模板接受任意数量和类型的参数,从根本上解决了传统重载函数带来的代码冗余和维护难题。这一机制通过模板参数包和函数参数包的递归展开或折叠表达式,实现了高度灵活且类型安全的接口设计,广泛应用于日志系统、元组容器、事件回调等场景。结合std::function和std::bind等包装器,可以统一管理各类可调

weixin_30768881的博客 283

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

C++ Lambda表达式:从语法到实战的完整指南

在C++编程中,函数对象和回调机制是构建灵活、可复用代码的基础。通过将函数作为参数传递,开发者可以实现策略模式、事件处理等高级设计模式,提升代码的模块化程度。Lambda表达式作为C++11引入的核心特性,本质上是一种轻量级的匿名函数对象,它允许开发者在需要函数的地方就地定义,无需额外命名。这一特性不仅简化了代码结构,还通过捕获列表实现了对外部变量的安全访问,包括值捕获、引用捕获以及C++14引入的初始化捕获。在工程实践中,Lambda与STL算法紧密结合,能够高效处理排序、筛选、变换等常见任务,同时避免了

weixin_30642869的博客 444

C++函数设计:从基础到实战,构建高效可维护代码

函数作为编程语言的核心概念,本质上是封装特定逻辑的代码单元,其设计质量直接影响软件的可维护性和性能。在C++中,函数不仅是执行任务的工具,更是实现代码复用、抽象和多态的基础。通过理解函数签名、参数传递机制(值、引用、指针)和返回策略,开发者可以编写出高效且安全的代码。现代C++进一步引入了Lambda表达式、std::function和函数模板等特性,极大地提升了代码的灵活性和表现力,尤其在事件回调、泛型编程等场景中价值显著。这些特性与函数式编程思想结合,使得C++能够应对从底层系统到高性能应用的多样化需求

weixin_30267785的博客 398

C++函数设计实战:从参数传递到lambda表达式的核心技巧

函数是编程语言中的基础概念,它通过封装特定功能实现代码复用和模块化。在C++中,函数的设计原理涉及参数传递机制(值传递、引用传递、指针传递)、作用域与生命周期管理,这些直接决定了程序的性能和安全性。函数的技术价值在于提升代码的可维护性和执行效率,特别是在构建复杂系统时,合理的函数设计能有效降低耦合度。在应用场景上,函数广泛应用于日志记录、网络通信、数据处理等模块开发。例如,在实现一个轻量级日志库时,通过函数封装不同级别的日志输出逻辑,可以避免代码重复;而在处理multipart/form-data的HTTP

weixin_30721077的博客 494
上一篇: libevent(17)evhttp的API及server端代码
下一篇: std::bind的讲解
老蔡编程
博客等级 码龄23年 48粉丝 75原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值