Шаблон std::function
ожидает в качестве аргумента тип функции, из которого он выводит тип возвращаемого значения и параметра для вызываемой обертки. Тип закрытия лямбда-выражения является вызываемым, но это не тип функции.
В C ++ 17 введены инструкции по выводу для std::function
, которые позволяют определить правильный тип из любого вызываемого аргумента. До C ++ 17 вы могли использовать набор вспомогательных шаблонов для определения правильного типа, например:
template <typename F>
struct deduce_func_type_helper;
template <typename R, typename... Args>
struct deduce_func_type_helper<R(&)(Args...)>
{
using type = std::function<R(Args...)>;
};
template <typename R, typename... Args>
struct deduce_func_type_helper<R(*)(Args...)> : deduce_func_type_helper<R(&)(Args...)> {};
template <typename C, typename R, typename... Args>
struct deduce_func_type_helper<R(C::*)(Args...)> : deduce_func_type_helper<R(&)(Args...)> {};
template <typename C, typename R, typename... Args>
struct deduce_func_type_helper<R(C::*)(Args...) const> : deduce_func_type_helper<R(&)(Args...)> {};
template <typename C, typename R, typename... Args>
struct deduce_func_type_helper<R(C::*)(Args...) volatile> : deduce_func_type_helper<R(&)(Args...)> {};
template <typename F>
struct deduce_func_type_helper<F&> : deduce_func_type_helper<std::remove_cv_t<F>> {};
template <typename F>
struct deduce_func_type_helper<F&&> : deduce_func_type_helper<std::remove_cv_t<F>> {};
template <typename F>
struct deduce_func_type_helper : deduce_func_type_helper<decltype(&F::operator())> {};
template <typename F>
using func_type_t = typename deduce_func_type_helper<F>::type;
живой пример здесь
Обратите внимание, что приведенный выше пример не завершен; в нем отсутствуют некоторые специализации, например, для всех возможных комбинаций const
, volatile
и различных квалификаторов ссылок. Так что это может быть довольно многословно, вам, вероятно, захочется использовать C ++ 17, если вы можете & hellip;