提问人:Dr.Random 提问时间:10/26/2022 最后编辑:Dr.Random 更新时间:10/26/2022 访问量:128
如何定义一个 lambda 函数以便能够捕获类的“this”指针?
How to define a lambda function to be able to capture the 'this' pointer of a class?
问:
我有一个跟踪时间的时间类。
我希望我的其他类能够在日期发生变化时注册回调函数。
我有这个工作片段:
#define MAX_CB_CHANGE_FUNCTIONS 50
typedef void (*dayChangeFunc)(int prevDay,int nowDay);
class TimeSystem {
private:
// array for the function pointers.
dayChangeFunc dayChangeFunctions[MAX_CB_CHANGE_FUNCTIONS];
// emit function if the day changes.
void emitDayChange(int prev, int now);
public:
void regDayChange(dayChangeFunc);
};
/*
* Registering a day change function.
* Maximum function pointer count is MAX_CB_CHANGE_FUNCTIONS ( see 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++;
}
/*
* Emitting day change to every registered function.
*/
void TimeSystem::emitDayChange(int prev, int now){
// Preventing change on initialization.
if( prev == 0 ){ return; }
for (size_t i = 0; i < MAX_CB_CHANGE_FUNCTIONS; i++){
if(dayChangeFunctions[i]){
dayChangeFunctions[i](prev,now);
}
}
}
这是有效的,其他 calsses 可以像这样使用它:
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 以便能够捕获“this”指针?
******** 编辑:已解决 ********
以下是修改:
我必须像这样定义我的 lambda 函数类型:
using dayChangeFunc = std::function<void(int, int)>;
定义函数指针寄存器函数,如下所示:
void regDayChange(dayChangeFunc cb);
并像这样重写声明:
/*
* Registering a day change function.
* Maximum function pointer count is MAX_CB_CHANGE_FUNCTIONS ( see 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++;
}
现在我可以在任何类中使用它,如下所示:
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++;
});
}
}
答:
0赞
lorro
10/26/2022
#1
捕获任何内容的 lambda 函数不能转换为函数指针。您需要手动传递指针,或者需要有一个函数“池”,每个函数全局存储当前指针。this
评论
0赞
Dr.Random
10/26/2022
我可以以某种方式使用它的std::函数吗?
0赞
lorro
10/26/2022
@Dr.随机 否,除非您在回调中也更改了它。 还需要一个指针。你所要求的东西在 c++ 中根本行不通。std::function
0赞
molbdnilo
10/26/2022
@lorro -capturing lambda 需要什么指针?this
0赞
Dr.Random
10/26/2022
调用它的整个类。
0赞
Dr.Random
10/26/2022
我正在各种类中注册一个回调函数,并想在回调中做与类相关的事情。
2赞
molbdnilo
10/26/2022
#2
将回调类型更改为std::function<void(int, int)>
using dayChangeFunc = std::function<void(int, int)>;
或
typedef std::function<void(int, int)> dayChangeFunc;
并更改功能原型,
void TimeSystem::regDayChange(dayChangeFunc func)
.
(如果您始终如一地使用类型别名,则无需更改原型,只需更改别名本身即可。如果使用类型别名,则它们最有用。
评论
0赞
Dr.Random
10/26/2022
非常感谢您的回答!您推荐使用关键字还是 typedef 关键字?
0赞
molbdnilo
10/26/2022
用。现在几乎没有人使用,甚至有些情况你不能使用。保持一致是一件好事。using
typedef
0赞
Dr.Random
10/26/2022
谢谢!我会读到更多使用的信息。
评论
std::function<void(int, int)>