我有以下类,它有一个名为errorHandler
的方法,需要使用几个不同的回调:
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);
};
我可以使用以下内容:
return errorHandler(GpioStatusCode::wrongArgumentsError, &IOPinHandler::ptrFun);
而且代码编译成功,运行如我所期望的那样。
我也可以用下面的方法传递lambda函数:
auto fix = [](IOPinHandler& obj) -> bool
{
return true;
};
return errorHandler(GpioStatusCode::wrongArgumentsError, static_cast<bool(*)(IOPinHandler&)>(fix));
这样,代码也可以成功编译和运行。
但是,如果我在lambda函数中添加capture,代码将无法编译:
auto fix = [&](IOPinHandler& obj) -> bool
{
return true;
};
return errorHandler(GpioStatusCode::wrongArgumentsError, fix);
我得到以下编译时错误:
error: no matching function for call to 'IOPinHandler::errorHandler(GpioStatusCode, IOPinHandler::init<GpioMode>::<lambda(IOPinHandler&)>&)'
12 | return errorHandler(GpioStatusCode::wrongArgumentsError, fix);
我想再加一句:
template<typename HandlerReturn = void, typename ...Args>
HandlerReturn errorHandler(const GpioStatusCode& code, const std::function<HandlerReturn(IOPinHandler&, const Args&...)>& callback, Args&... args);
将匹配接收lambda函数作为参数的模板示例化,但事实上,我不得不强制转换不带捕获的lambda,而带捕获的lambda也不起作用,这有点暗示我,只有第一个定义或“errorHandler
“被调用。
我的推理是对的吗?我怎么能通过呢?
编辑:完整代码。
#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;
}
1条答案
按热度按时间euoag5mw1#
如果我理解正确的话,您不需要任何成员函数重载,甚至不需要
std::function
。您可以将
Callable
作为模板参数,并让编译器为您推导它的类型。Live Demo