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

如何定义Lambda函数以捕获类的this指针?

问题:带捕获的Lambda无法转换为函数指针作为日期变化回调

我有一个用于跟踪时间的TimeSystem类,允许其他类在日期变化时注册回调函数。现有可正常运行的代码片段如下:

#define MAX_CB_CHANGE_FUNCTIONS 50
typedef void (*dayChangeFunc)(int prevDay,int nowDay);

class TimeSystem {
    private:
        // 存储函数指针的数组
        dayChangeFunc dayChangeFunctions[MAX_CB_CHANGE_FUNCTIONS];
        // 日期变化时触发的函数
        void emitDayChange(int prev, int now);
    public:
        void regDayChange(dayChangeFunc);
};


/*
*   注册日期变化回调函数
*   最大函数指针数量为MAX_CB_CHANGE_FUNCTIONS(详见timeSys.h)
*/
void TimeSystem::regDayChange(void (*dayChangeFunc)(int prevDay,int nowDay)){
    if( currDayCbIndex >= MAX_CB_CHANGE_FUNCTIONS ){
        if(isDebugOn){
            debug.print(DEBUG_WARN,"[Time_sys] - Can not register an other day change function.\n");
            return;
        }
    }
    dayChangeFunctions[currDayCbIndex] = dayChangeFunc;
    currDayCbIndex++;
}

/*
*   向所有已注册函数触发日期变化事件
*/
void TimeSystem::emitDayChange(int prev, int now){
    // 初始化时不触发
    if( prev == 0 ){ return; }
    for (size_t i = 0; i < MAX_CB_CHANGE_FUNCTIONS; i++){
        if(dayChangeFunctions[i]){
            dayChangeFunctions[i](prev,now);
        }
    }
}

其他类原本可以通过无捕获的Lambda使用该功能:

timeSys.regDayChange([](int prevDay,int nowDay){
    Serial.printf("Day changed from prev: %d to now: %d\n",prevDay,nowDay);
});

当尝试在Lambda中捕获this指针以调用类内部函数时:

timeSys.regDayChange([this](int prevDay,int nowDay){
    callSomeInternalFunction();
});

出现编译错误:

no suitable conversion function from "lambda [](int prevDay, int nowDay)->void" to "dayChangeFunc"
解决方案

问题根源是带有捕获的Lambda无法隐式转换为普通函数指针,需要改用std::function来存储回调。具体修改如下:

  1. 修改回调类型定义
    将原有的函数指针类型替换为std::function:
using dayChangeFunc = std::function<void(int, int)>;
  1. 更新注册函数的声明
    在TimeSystem类的public接口中修改注册函数:
void regDayChange(dayChangeFunc cb);
  1. 改写注册函数的实现
/*
*   注册日期变化回调函数
*   最大函数指针数量为MAX_CB_CHANGE_FUNCTIONS(详见timeSys.h)
*/
void TimeSystem::regDayChange( dayChangeFunc cb ){
    if( currDayCbIndex >= MAX_CB_CHANGE_FUNCTIONS ){
        if(isDebugOn){
            debug.print(DEBUG_WARN,"[Time_sys] - Can not register an other day change function.\n");
            return;
        }
    }
    dayChangeFunctions[currDayCbIndex] = cb;
    currDayCbIndex++;
}

修改完成后,即可在类中使用带this捕获的Lambda注册回调:

class SampleClass {
  private:
     int exampleCounter = 0;
  public:
    void init(){
      TimeSystem timeSys;
      timeSys.regDayChange([this](int prevDay,int nowDay){
        Serial.printf("Day changed from prev: %d to now: %d\n",prevDay,nowDay);
        exampleCounter++;
      });
    }
};

内容的提问来源于stack exchange,提问作者Dr.Random

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:55:18