#c #boost #recursion #metaprogramming
#c #повышение #рекурсия #метапрограммирование
Вопрос:
Допустим, у меня есть последовательность MPL types
длиной N
(например boost::variant<int,string,double>
, и последовательность типов boost::variant::types
):
Я хотел бы рекурсивно сгенерировать следующий код для каждого возможного индекса. Именно то, что операторы if выполняются до w==N
void make(int w){
if(w == 0){
typename boost::mpl::at_c<types,0>::type t;
// Some code
}else if (w==1){
typename boost::mpl::at_c<types,1>::type t;
// Some code
}...
.
.
.
}else if(w==N){
typename boost::mpl::at_c<types,2>::type t;
// Some code
}else{
// Runtime ERROR
}
}
Как я могу этого добиться?
Ответ №1:
Как общее эмпирическое правило, поскольку вы пытаетесь что-то делать во время компиляции, ваша рекурсия также будет выполняться во время компиляции. Это сразу подразумевает, что вам понадобится статическая (типовая) функция, которая реализует рекурсию и условие остановки.
Если вы хотите получить код, аналогичный тому, что показывает ваш псевдокод, вы можете использовать Boost Fusion, который содержит алгоритмы, имитирующие знакомые алгоритмы выполнения, например boost::fusion::for_each
.
В Fusion также есть ассоциативные коллекции ( boost::fusion::map<...>
), которые могут соответствовать вашему варианту использования.
Комментарии:
1. (публикую это уже из-за нехватки времени. Возможно, я найду время для уточнения примера позже)
2. это было бы действительно полезно!
Ответ №2:
template <int N>
void make(int w)
{
if(w>N)
{
make<-1>(w);
}
if(w==N)
{
typename boost::mpl::at_c<types, N>::type t;
// Some code
}
else
make<N-1>(w);
}
template <>
void make<-1>(int w)
{
// Runtime ERROR
}
РЕДАКТИРОВАТЬ : включен комментарий sehe.
Комментарии:
1. вы могли бы удалить дублирование, вызвав
make<-1>(0)
if(w>N)