[英]c++ template parameter compiler can not deduce
here is function to register.这里是 function 注册。
template <typename ReqT, typename RespT>
bool RegisterCmdHandler(int cmd_id, std::function<int(int, const ReqT&, RespT&)> sync_handler) {
// ... do something with sync_handler and register it for later callback
return true;
}
and a specific handler to register:以及要注册的特定处理程序:
int SomeHandler(int id, const Foo& req, Bar& resp) {
// ... specific logic
}
now I want to apply the Handler to Register Function, compiler complains现在我想将处理程序应用于注册 Function,编译器抱怨
RegisterCmdHandler(1, SomeHandler); // ERROR, compiler can not deduce
while specificly write out the type is OK:而具体写出类型是可以的:
RegisterCmdHandler<Foo, Bar>(1, SomeHandler); // OK, compiler can deduce
but the latter has ugly API.但后者有丑陋的API。 How can I get the first on work?
我怎样才能在工作中获得第一名?
How can I get the first on work?
我怎样才能在工作中获得第一名?
Add an overload for plain function pointers:为普通的 function 指针添加重载:
template <typename ReqT, typename RespT>
bool RegisterCmdHandler(int cmd_id, int(*sync_handler)(int, const ReqT&, RespT&)) {
std::function<int(int, const ReqT&, RespT&)> sync_handler2(sync_handler);
return RegisterCmdHandler(cmd_id, sync_handler2);
}
How can I get the first on work?
我怎样才能在工作中获得第一名?
I see some ways.我看到了一些方法。
(1) If you can modify the RegisterCmdHandler()
function and you don't need to know, inside it, what types ReqT
and RestT
are, I suggest you to avoid at all std::function
and accept sync_handler
as a simple template type. (1) 如果您可以修改
RegisterCmdHandler()
function并且您不需要知道其中ReqT
和RestT
是什么类型,我建议您完全避免std::function
并接受sync_handler
作为简单的模板类型.
I mean我是说
template <typename F>
bool RegisterCmdHandler (int cmd_id, F sync_handler) {
// ... do something with sync_handler
return true;
}
This is a very flexible solution because F
can be a function, a function pointer, a std::function
, a lambda (also a generic lambda, so this solution is more flexible than using std::function
), another type of class/struct with an operator()
, a value returned from a std::bind
. This is a very flexible solution because
F
can be a function, a function pointer, a std::function
, a lambda (also a generic lambda, so this solution is more flexible than using std::function
), another type of class/带有operator()
的结构,从std::bind
返回的值。 In short: a generic callable.简而言之:一个通用的可调用对象。
(2) If you can modify the RegisterCmdHandler()
function but you need to know (and use) the ReqT
and RestT
, you can follows the plain function pointer way (see Maxim Egorushkin's answer for the syntax). (2) 如果您可以修改
RegisterCmdHandler()
function但您需要了解(并使用) ReqT
和RestT
,则可以遵循普通的 function 指针方式(有关语法,请参见 Maxim Egorushkin 的答案)。 Unfortunately this works with function pointers only and doesn't works (by example) when sync_handler
is a lambda.不幸的是,这仅适用于 function 指针,并且当
sync_handler
是 lambda 时(例如)不起作用。
(3) If you can't modify RegisterCmdHandler()
but you can use C++17, you can use std::function
deduction guides and call the function as follows (3)如果不能修改
RegisterCmdHandler()
但是可以使用C++17,可以使用std::function
推导指引,调用ZC1C425268E68385D1AB5074C17A94F1
RegisterCmdHandler(1, std::function{SomeHandler});
or, maybe better if you have to call it in different places, call it through a converter或者,如果您必须在不同的地方调用它,可能会更好,通过转换器调用它
template <typename F>
auto CallRegisterCH (int cmd_if, F && func)
{ return RegisterCmdHandler(cmd_if, std::function{std::forward<F>(func)}); }
calling it as follows如下调用它
CallRegisterCH(1, SomeHandler);
(4) if you can't modify RegisterCmdHandler()
and you have to use C++11 or C++14... well... explicating the template types (4) 如果你不能修改
RegisterCmdHandler()
并且你必须使用 C++11 或 C++14...好吧...解释模板类型
RegisterCmdHandler<Foo, Bar>(1, SomeHandler);
seems to me the better way.在我看来是更好的方法。
Other ways you can explicit the std::function
其他可以显式
std::function
的方式
std::function<int(int, Foo const &, Bar &)> sh{ SomeHandler };
RegisterCmdHandler(1, sh);
but seems to me almost the same thing.但在我看来几乎是一样的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.