I have this case, I can't figure it out.
I want to add a function in a vector of functions from an object to his child like this:
Child:
std::vector<void (*)(STATE oldState, STATE newState)> stateChangeHandlers;
void Digital_Output::addOnStateChangeHandler(void (*function)(STATE oldState, STATE newState)) {
this->stateChangeHandlers.push_back(function);
}
Parent / Owner
Digital_Outputs::Digital_Outputs(json outputsConf) { //nlohmann::json
int idx = 0;
for (auto output: outputsConf) {
Digital_Output *DO = new Digital_Output(output["pin"].get<int>(), idx);
//from here
DO->addOnStateChangeHandler([DO](STATE oldState, STATE newState) -> void*{ //note the capture
json j;
j["state"] = newState;
std::string jsonStr = j.dump();
mqtt::message_ptr pubmsg = mqtt::make_message(std::string(this->getTopicBase() "/" DO->getName()), &jsonStr); //note the this
});
//to here
this->addOutput(DO);
std::cout << "Added Output name: " << DO->getName() << " forced: " << BoolToString(DO->isForced()) << ":" << DO->getForcedValue() << " retain: " << BoolToString(DO->isRetain()) << ": " << DO->getRetainValue() << " comment: " << DO->getComment() << std::endl;
idx ;
}
}
VSCode tell me :
there is no proper conversion function from "lambda []void *(STATE oldState, STATE newState)->void *" to "void (*)(STATE oldState, STATE newState)"
Next, functions stored are executed by:
void Digital_Output::_onStateChange(STATE oldState, STATE newState) {
for(std::vector<void (*)(STATE oldState, STATE newState)>::iterator it = std::begin(this->stateChangeHandlers); it != std::end(this->stateChangeHandlers); it) {
(*it)(oldState, newState);
}
}
CodePudding user response:
Your vector holds C-style function pointers. However, a capturing lambda cannot be converted to a function pointer (which is what the error message is trying to tell you), only a non-capturing lambda can. To store capturing lambdas, you will have to use std::function
instead.
Also, your lambda returns a void*
, but your vector expects functions that return void
instead.
Also, your lambda is trying to use this
without capturing it.
Try this instead:
Child
using stateHandlerFunc = std::function<void(STATE, STATE)>;
std::vector<stateHandlerFunc> stateChangeHandlers;
void Digital_Output::addOnStateChangeHandler(stateHandlerFunc function) {
stateChangeHandlers.push_back(function);
}
Parent / Owner
Digital_Outputs::Digital_Outputs(json outputsConf) { //nlohmann::json
int idx = 0;
for (auto output: outputsConf) {
Digital_Output *DO = new Digital_Output(output["pin"].get<int>(), idx);
DO->addOnStateChangeHandler(
[this, DO](STATE oldState, STATE newState) {
json j;
j["state"] = newState;
std::string jsonStr = j.dump();
mqtt::message_ptr pubmsg = mqtt::make_message(std::string(this->getTopicBase() "/" DO->getName()), &jsonStr);
}
);
addOutput(DO);
std::cout << "Added Output name: " << DO->getName() << " forced: " << BoolToString(DO->isForced()) << ":" << DO->getForcedValue() << " retain: " << BoolToString(DO->isRetain()) << ": " << DO->getRetainValue() << " comment: " << DO->getComment() << std::endl;
idx ;
}
}
void Digital_Output::_onStateChange(STATE oldState, STATE newState) {
for(auto&& handler : stateChangeHandlers) {
handler(oldState, newState);
}
}