Я предлагаю следующее make_signature
template <typename T, std::size_t>
using getType = T;
template <typename, typename, std::size_t N,
typename = std::make_index_sequence<N>>
struct make_signature;
template <typename R, typename T, std::size_t N, std::size_t ... Is>
struct make_signature<R, T, N, std::index_sequence<Is...>>
{ using type = R(*)(getType<T, Is>...); };
Но есть проблема: когда вы пишете
template <typename R, typename T, std::size_t N>
void my_generalized_hof (typename make_signature<R, T, N>::type param)
{
// do something with param
}
часть make<R, T, N>
находится в не-выводимом контексте (до ::
), поэтому R
, T
и N
не могут быть выведены из аргумента.
Я имею в виду ... вы не можете вызвать
my_generalized_hof(&my_function2);
Вы должны указать аргументы шаблона следующим образом
// ...............VVVVVVVVVVVVVVV
my_generalized_hof<void, int, 2u>(&my_function2);
Ниже приведен полный пример компиляции
#include <utility>
#include <vector>
#include <type_traits>
void my_function2(int x1, int x2) {}
void my_function2(int x1, int x2, std::vector<int> other) {}
template <typename T, std::size_t>
using getType = T;
template <typename, typename, std::size_t N,
typename = std::make_index_sequence<N>>
struct make_signature;
template <typename R, typename T, std::size_t N, std::size_t ... Is>
struct make_signature<R, T, N, std::index_sequence<Is...>>
{ using type = R(*)(getType<T, Is>...); };
template <typename R, typename T, std::size_t N>
void my_generalized_hof (typename make_signature<R, T, N>::type param)
{
// do something with param
}
int main ()
{
my_generalized_hof<void, int, 2u>(&my_function2);
}