Expand type N times in the template parameter

I have the following problem:

template< std::size_t N > class A { std::function< std::size_t( /*std::size_t,....,std::size_t <- N-times*/) > foo; }; 

As you can see above, I am trying to declare std::function<...> foo as a member of class A Here, I want foo to have the return type std::size_t (which does not present a problem), and as input I will pass the std::size_t type N times, but I do not know how to do this. Is there a possibility?

Thank you very much in advance.

+8
c ++ templates c ++ 14 std-function
source share
3 answers

You can use std::index_sequence :

 template<typename> struct AHelper; template<std::size_t... S> struct AHelper<std::index_sequence<S...>> { std::function<std::size_t(decltype(S)...)> foo; }; template<std::size_t N> struct A : AHelper<std::make_index_sequence<N>> {}; 

Live example at coliru

If you like, you can also determine what type it expands to:

 template<typename, typename> struct AHelper; template<typename T, std::size_t... S> struct AHelper<T, std::index_sequence<S...>> { template<std::size_t> using type = T; std::function<std::size_t(type<S>...)> foo; }; template<typename T, std::size_t N> struct A : AHelper<T, std::make_index_sequence<N>> {}; 
+12
source share

For an arbitrary type, not just size_t just write an auxiliary alias:

 template<class T, size_t> using Type = T; template<std::size_t... S> struct AHelper<std::index_sequence<S...>> { std::function<size_t(Type<MyArbitraryTypeHere, S>...)> foo; }; 
+2
source share

Well, that was fun. Here is my solution:

 namespace details { template <size_t N, class F = size_t()> struct Function_type_helper {}; template <size_t N, class... Args> struct Function_type_helper<N, size_t(Args...)> { using Type = typename Function_type_helper<N - 1, size_t(Args..., size_t)>::Type; }; template <class... Args> struct Function_type_helper<0, size_t(Args...)> { using Type = size_t(Args...); }; template <size_t N, class F = size_t()> using Function_type_helper_t = typename Function_type_helper<N, F>::Type; static_assert(std::is_same_v<Function_type_helper_t<3>, size_t(size_t, size_t, size_t)>); } // ns details template<size_t N> struct A { std::function<details::Function_type_helper_t<N>> foo; }; 

This works by recursively creating the type size_t(size_t, size_t, ..., size_t)

For example:

 H<3>::Type == H<3, size_t()>::Type == H<2, size_t(size_t)>::Type == H<1, size_t(size_t, size_t)>::Type == H<0, size_t(size_t, size_t, size_t)>::Type == size_t(size_t, size_t, size_t) 
+1
source share

All Articles