mpl序列和递归代码生成

时间:2014-06-24 11:40:53

标签: c++ boost recursion metaprogramming

假设我有长度为types的MPL序列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
    }
}

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

作为一般的经验法则,既然您在编译时尝试做事,那么您的递归也将是编译时间。这立即意味着您需要一个实现递归和停止条件的静态(类型)函数。

如果你想要实现类似于伪代码显示的代码,可以使用Boost Fusion,它包含模仿熟悉的运行时算法的算法,如boost::fusion::for_each

Fusion还具有可能适合您用例的关联集合(boost::fusion::map<...>)。

答案 1 :(得分:0)

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                                                                                                          
}

编辑:纳入了评论。