Given the type of a callable function C
, I want to get at compile time a std::function
; the type of which:
C
N
argument types of function C
This means that, for a given type void(int, char, double)
and a given N
, the type of the function is:
N = 1
=> result type: std::function<void(int)>
N = 2
=> result type: std::function<void(int, char)>
N = 3
=> result type: std::function<void(int, char, double)>
N > 3
=> compile time errorExample:
template<std::size_t N, typename R, typename... A>
constexpr auto get() {
return /*(magically somehow)*/ std::function<R(FirstNFromA...)>
}
template<std::size_t N, typename R, typename... A>
struct S {
using func = decltype(get<N, R, A...>());
};
It follows a possible solution:
#include <tuple>
#include <utility>
#include <functional>
#include <type_traits>
template<
typename R,
typename... A,
std::size_t... I,
std::enable_if_t<(sizeof...(I)<=sizeof...(A))>* = nullptr
> constexpr auto
get(std::integer_sequence<std::size_t, I...>) {
return std::function<R(std::tuple_element_t<I, std::tuple<A...>>...)>{};
}
template<std::size_t, typename>
struct FuncType;
template<std::size_t N, typename R, typename... A>
struct FuncType<N, R(A...)> {
using Type = decltype(get<R, A...>(std::make_index_sequence<N>{}));
};
int main() {
static_assert(
std::is_same<
FuncType<2, void(int, char, double, int)>::Type,
std::function<void(int, char)>
>::value,
"!"
);
}
The basic idea is to use a tuple
and those utilities that are part of the Standard template Library (as an example, std::tuple_element
), mix them with a pack expansion placed in the right place and that's all.
To do that, I used a constexpr
function that returns an empty std::function
object of the given type. Then the type of the function is taken by means of a decltype
and exported as a type of the FuncType
object using an alias.
Everything takes place at compile time.
In order to deduce the right type for that function, I used a well known pattern that involves a std::integer_sequence
and actually unpack the types of a tuple by expanding the indexes.