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!!

Community
  • 1
  • 1

2 Answers2

4

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>());
}
T.C.
  • 133,968
  • 17
  • 288
  • 421
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

Daniel Frey
  • 55,810
  • 13
  • 122
  • 180
  • I like this approach, unfortunately I cannot use (for the moment) c++14 – Alberich2k5 Jun 11 '15 at 11:16
  • @Alberich2k5 It should work with C++11, all you need is an implementation for `std::make_index_sequence` etc. but that can be done with C++11 as well. I was just using C++14 in the answer to avoid copy-pasting yet another solution for `std::integer_sequence`. Additional benefit if you use a compatible interface: The switch to C++14 will be easier in the future. – Daniel Frey Jun 11 '15 at 12:12