2015-06-10 7 views
1

Возможно ли создать пакет шаблонов шаблонов?C++ 11 Сгенерировать аргументы шаблона

У меня есть следующий код работы:

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

Моя цель состоит в том, чтобы сформировать список 0,1,2 во время компиляции, как она будет использоваться с переменным числом шаблонов, например:

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

Мне нужно, чтобы это было сгенерировано во время компиляции, так как расширение запускает некоторые шаблонные функции, которые оптимизируются в зависимости от типа слоя/фильтра, поэтому я могу запустить другой код. Идея заключается в том, чтобы определить список слоев или фильтров, сгенерированных во время компиляции, и удалить некоторые ifs (и другие ситуации), поскольку это будет использоваться в среде HPC (и находится внутри критического пути).

Это внутри этого класса (упрощенный вариант):

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); 
} 
}; 

Я также попытался решения, предложенные на сайте:

Implementation C++14 make_integer_sequence

How do I generate a variadic parameter pack?

Но ни один из них не работает для меня. Я получаю эту ошибку:

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

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

Любое предложение? спасибо!

ответ

3

Вам нужен помощник:

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>()); 
} 
+0

Это сработало! Большое спасибо – Alberich2k5

1

Кроме того, решения, которые @ T.C. показал, вы также можете сделать что-то похожее на работу zip<make_sequence<3>>. Это будет выглядеть следующим образом:

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

Реализация такого помощника является:

#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

+0

Мне нравится этот подход, к сожалению, я не могу использовать (на данный момент) C++ 14 – Alberich2k5

+0

@ Alberich2k5 Он должен работать с C++ 11, все, что вам нужно, это реализация для 'std :: make_index_sequence' и т. д. но это можно сделать и с C++ 11. Я просто использовал C++ 14 в ответ, чтобы избежать копирования в другое еще одно решение для 'std :: integer_sequence'. Дополнительное преимущество, если вы используете совместимый интерфейс: переход на C++ 14 будет проще в будущем. –