Another solution might be:
#include <tuple> #include <utility> #include <functional> #include <type_traits> template <size_t N, class R, class Pack, class ResultPack, class Voider> struct FuncTypeImpl; template <size_t N, class R, template <class...> class Pack, class First, class... Args, class... ResultArgs> struct FuncTypeImpl<N, R, Pack<First, Args...>, Pack<ResultArgs...>, std::enable_if_t<(N > 0)>>: FuncTypeImpl<N-1, R, Pack<Args...>, Pack<ResultArgs..., First>, void> { using typename FuncTypeImpl<N-1, R, Pack<Args...>, Pack<ResultArgs..., First>, void>::Type; }; template <size_t N, class R, template <class...> class Pack, class... Args, class... ResultArgs> struct FuncTypeImpl<N, R, Pack<Args...>, Pack<ResultArgs...>, std::enable_if_t<(N == 0)>> { using Type = std::function<R(ResultArgs...)>; }; template<std::size_t, typename> struct FuncType; template<std::size_t N, typename R, typename... A> struct FuncType<N, R(A...)> { using Type = typename FuncTypeImpl<N, R, std::tuple<A...>, std::tuple<>, void>::Type; }; int main() { static_assert( std::is_same< FuncType<3, void(int, char, double, int)>::Type, std::function<void(int, char, double)> >::value, "!" ); }
Edit: Another one, maybe a little simpler (which does not require a solution to std :: tuple):
#include <utility> #include <functional> #include <type_traits> template <class T> struct ResultOf; template <class R, class... Args> struct ResultOf<R(Args...)> { using Type = R; }; template<std::size_t N, class Foo, class ResultFoo = typename ResultOf<Foo>::Type() , class Voider = void> struct FuncType; template<std::size_t N, class R, class First, class... Args, class... ResultArgs > struct FuncType<N, R(First, Args...), R(ResultArgs...), std::enable_if_t<(N > 0)>>: FuncType<N-1, R(Args...), R(ResultArgs..., First), void> { }; template<std::size_t N, class R, class First, class... Args, class... ResultArgs > struct FuncType<N, R(First, Args...), R(ResultArgs...), std::enable_if_t<(N == 0)>> { using Type = std::function<R(ResultArgs...)>; }; int main() { static_assert( std::is_same< FuncType<3, void(int, char, double*, int)>::Type, std::function<void(int, char, double*)> >::value, "!" ); }