Как я могу получить первый на работе?
Я вижу несколько способов.
(1) Если вы можете изменить функцию RegisterCmdHandler()
и вам не нужно знать внутри, какие типы ReqT
и RestT
, я предлагаю вам вообще избегать std::function
и принять sync_handler
в качестве простого типа шаблона.
Я имею в виду
template <typename F>
bool RegisterCmdHandler (int cmd_id, F sync_handler) {
// ... do something with sync_handler
return true;
}
Это очень гибкое решение, потому что F
может быть функцией, указателем на функцию, std::function
, лямбда-выражением (также общим лямбда, так что это решениеболее гибкий, чем использование std::function
), другой тип класса / структуры с operator()
, значением, возвращаемым из std::bind
.Вкратце: универсальный вызываемый.
(2) Если вы можете изменить функцию RegisterCmdHandler()
, но , вам нужно знать (и использовать) ReqT
и RestT
, выМожет следовать обычному указателю на функцию (синтаксис см. в ответе Максима Егорушкина).К сожалению, это работает только с указателями на функции и не работает (например), когда sync_handler
является лямбда-выражением.
(3) Если вы не можете изменить RegisterCmdHandler()
, но вы можете использовать C ++ 17, вы можете использовать std::function
руководства по удержанию и вызывать функцию следующим образом
RegisterCmdHandler(1, std::function{SomeHandler});
или, может быть, лучше, если вам придется вызывать ее в разных местах, вызывать ее через конвертер
template <typename F>
auto CallRegisterCH (int cmd_if, F && func)
{ return RegisterCmdHandler(cmd_if, std::function{std::forward<F>(func)}); }
вызывая его следующим образом
CallRegisterCH(1, SomeHandler);
(4), если вы не можете изменить RegisterCmdHandler()
и вам нужно использовать C ++ 11 или C ++ 14 ... хорошо ... объясняятипы шаблонов
RegisterCmdHandler<Foo, Bar>(1, SomeHandler);
кажутся мне лучшим способом.
Другие способы, которыми вы можете явно указать std::function
std::function<int(int, Foo const &, Bar &)> sh{ SomeHandler };
RegisterCmdHandler(1, sh);
, но мне кажется, почти то же самое.