I have a time class which tracks the time.
I want my other classes to be able to register a callback function if the day changes.
I have this working snippet:
#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);
}
}
}
This works and other calsses can use this like this:
timeSys.regDayChange([](int prevDay,int nowDay){
Serial.printf("Day changed from prev: %d to now: %d\n",prevDay,nowDay);
});
Now i want to capture the 'this' pointer in the lambda to be able to call some internal function of a class.
timeSys.regDayChange([this](int prevDay,int nowDay){
callSomeInternalFunction();
});
Error i get:
no suitable conversion function from "lambda [](int prevDay, int nowDay)->void" to "dayChangeFunc"
How could i define my lambda to be able to capture the 'this' pointer?
******** EDIT: SOLVED ********
Here are the modifications:
I had to define my lambda function type like this:
using dayChangeFunc = std::function<void(int, int)>;
Define the function pointer register function like this:
void regDayChange(dayChangeFunc cb);
And rewrite the declaration like this:
/*
* 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++;
}
And now i can use it in any class like this:
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++;
});
}
}
Change the callback type to std::function<void(int, int)>
using dayChangeFunc = std::function<void(int, int)>;
or
typedef std::function<void(int, int)> dayChangeFunc;
and change the function prototype,
void TimeSystem::regDayChange(dayChangeFunc func)
.
(If you had used your type alias consistently you wouldn't have needed to change the prototype, only the alias itself. Type aliases are most useful if you use them.)