C++11 Generate template arguments

Refresh

December 2018

Views

117 time

1

Is it possible to generate somehow template argument pack?

I have the following code working:

zip<0,1,2>.expand(c);

My goal is to generate the list 0,1,2 at compile time as it is going to be used with variadic templates, for example:

zip<make_sequence<3>>.expand(c);

I need this to be generated at compile time, as expand triggers some templated functions which gets optimized depending on the Layer/Filter type so I can launch other code. The idea behind this is to be able to determine a list of Layers or filters generated at compilation time and remove some ifs (and other situations) as this is going to be used un HPC environments (and is inside the critical path).

This is inside this class (simplified version):

template<class... Layer>
class TRAV{  
  template <int...CS> struct zip{
    static void expand(int c){
      constexpr int b = sizeof...(Layers); 
      expand2((TRAV::path<CS,b,typename Layers::MONAD_TYPE>(c),0)...);
    }
  template<typename...IS>
    static void expand2(IS&&...) {
    }
 };
 void call(int c){ 
  zip<0,1,2>.expand(c); 
 }
};

I also tried solutions proposed at:

Implementation C++14 make_integer_sequence

How do I generate a variadic parameter pack?

But none of them worked for me. I get this error:

error: type/value mismatch at argument 1 in template parameter list for >‘template

error: expected a constant of type ‘int’, got ‘make_integer_sequence’

Any suggestion? Thank you very much!!

2 answers

3

You need a helper:

template<int... Seq>
void call(int c, std::integer_sequence<int, Seq...>){
    zip<Seq...>::expand(c);
}

void call(int c){ 
    call(c, std::make_integer_sequence<int, 3>());
}
1

Besides the solution that @T.C. has shown, you can also make something similar to zip<make_sequence<3>> work. It would look like this:

apply_indices<zip<>,std::make_index_sequence<3>>

The implementation of such a helper is:

#include <utility>

template<typename,typename> struct apply_indices_impl;

template<typename T,template<T...> class C,T... Ns>
struct apply_indices_impl<C<>,std::integer_sequence<T,Ns...>>
{
    using type = C<Ns...>;
};

template<typename T,typename I>
using apply_indices = typename apply_indices_impl<T,I>::type;

Live example