Что вам нужно, так это черта типа, которая обеспечивает доступ к типам, используемым в сигнатуре функции. В стандартной библиотеке нет такой черты типа. Таким образом, вам нужно либо использовать библиотеку, которая ее реализует, либо реализовать ее самостоятельно.
Если вы можете использовать boost, они точно реализовали это в своих чертах типа: https://www.boost.org/doc/libs/1_68_0/libs/type_traits/doc/html/boost_typetraits/reference/function_traits.html Вы могли бы использовать член argN_type
, чтобы получить тип аргумента N-го типа.
Если вы не можете использовать boost, вам нужно будет реализовать собственную черту типа, чтобы сделать типы аргументов доступными. Это может выглядеть так:
// Base case for non-function types
template<typename T>
struct func_types { };
// Case for any generic function signature
template<typename Return, typename ...Args>
struct func_types<Return(Args...)>
{
using ReturnType = Return;
using ArgsTuple = std::tuple<Args...>;
template<std::size_t N>
struct args
{
using Type = std::tuple_element_t<N, ArgsTuple>;
};
};
// Specialization for function pointers
template<typename Return, typename ...Args>
struct func_types<std::function<Return(Args...)>> : public func_types<Return(Args...)> { };
// Specialization for std::function
template<typename Return, typename ...Args>
struct func_types<std::function<Return(Args...)>> : public func_types<Return(Args...)> { };
// All further specializations for member functions,
// lambdas, etc. are left as an exercise to the reader
template<typename Func>
void execute(Func func, typename func_types<Func>::template args<0>::Type t)
{
std::cout << func(t) << std::endl;
}
Этот пример является в основном урезанной версией этого сообщения в блоге . При этом используются функции, добавленные в C ++ 14, поэтому вам нужно будет скомпилировать эту версию или более новую.