I have the following class who has a method called errorHandler
that needs to use several different callbacks:
class IOPin;
class IOPinHandler
{
IOPinHandler();
virtual ~IOPinHandler();
static bool ptrFun(IOPinHandler&) { return true; };
template<typename T>
bool init(IOPin& obj, const T& param);
template<typename HandlerReturn = void, typename ...Args>
HandlerReturn errorHandler(const GpioStatusCode& code, HandlerReturn(*callback)(IOPinHandler& obj, const Args&...), const Args&... args);
// Added this overload to support passing lambdas as arguments,
// however does not seems to be called
template<typename HandlerReturn = void, typename ...Args>
HandlerReturn errorHandler(const GpioStatusCode& code, const std::function<HandlerReturn(IOPinHandler&, const Args&...)>& callback, Args&... args);
};
I can use the following:
return errorHandler(GpioStatusCode::wrongArgumentsError, &IOPinHandler::ptrFun);
And the code compiles successfully and runs as I expect it to do.
I can also use pass a lambda function in the following way:
auto fix = [](IOPinHandler& obj) -> bool
{
return true;
};
return errorHandler(GpioStatusCode::wrongArgumentsError, static_cast<bool(*)(IOPinHandler&)>(fix));
This way, the code also compiles and runs successfully.
However, if I add capture to the lambda function, the code won't compile:
auto fix = [&](IOPinHandler& obj) -> bool
{
return true;
};
return errorHandler(GpioStatusCode::wrongArgumentsError, fix);
I get the following compile time error:
error: no matching function for call to 'IOPinHandler::errorHandler(GpioStatusCode, IOPinHandler::init<GpioMode>::<lambda(IOPinHandler&)>&)'
12 | return errorHandler(GpioStatusCode::wrongArgumentsError, fix);
I thought that adding:
template<typename HandlerReturn = void, typename ...Args>
HandlerReturn errorHandler(const GpioStatusCode& code, const std::function<HandlerReturn(IOPinHandler&, const Args&...)>& callback, Args&... args);
Would match the template instantiation for receiving the lambda function as argument, but the fact that I have to cast the lambda without capture and that the lambda with capture does not work either, kinda suggest to me that only the first definition or "errorHandler
" is being invoked.
Is my reasoning right? How could I get pass this?
Edit: Full code.
#include <functional>
class IOPin;
class IOPinHandler
{
public:
template<typename ...T>
IOPinHandler(const T&... args);
virtual ~IOPinHandler();
static bool ptrFun(IOPinHandler&);
template<typename T>
bool init(const T& param);
template<typename HandlerReturn = void, typename ...Args>
HandlerReturn errorHandler(const int& code, HandlerReturn(*callback)(IOPinHandler& obj, const Args&...), const Args&... args);
// Added this overload to support passing lambdas as arguments,
// however does not seems to be called
template<typename HandlerReturn = void, typename ...Args>
HandlerReturn errorHandler(const int& code, const std::function<HandlerReturn(IOPinHandler&, const Args&...)>& callback, Args&... args);
};
template<typename ...T>
IOPinHandler::IOPinHandler(const T&... args)
{
(init(args),...);
}
bool IOPinHandler::ptrFun(IOPinHandler&)
{
return true;
}
template<typename T>
bool IOPinHandler::init(const T& param)
{
// Compiles with no problem
// return errorHandler(1, &IOPinHandler::ptrFun);
// Compiles with no problem
// auto fix = [](IOPinHandler& obj) -> bool
// {
// return true;
// };
// return errorHandler(1, static_cast<bool(*)(IOPinHandler&)>(fix));
// Does not compiles
auto fix = [&](IOPinHandler& obj) -> bool
{
return true;
};
return errorHandler(1, fix);
}
int main(void)
{
IOPinHandler a(1,'c',true);
return 0;
}
Aucun commentaire:
Enregistrer un commentaire