2011-01-12 113 views
0


我尝试使用元编程调用函数void set(...)递归。
问题是,它似乎只调用一次。元编程模板递归不递归(编辑重要)

template <int N> 
struct GEN 
{ 
    enum {value = GEN<N-1>::value}; 
    template <typename T> 
    static inline void set(T& tup, int l_item) 
    { 
     cout<<"item value: "<<l_item<<", N-1: "<< N-1 << ", value: "<<value <<endl; 
     typedef typename boost::tuples::element<N-1, T>::type _el_type; 
     get<N-1>(tup) = atomic_item<N-1, _el_type>(l_item); 
    }; 
}; 

template<> 
struct GEN<0> 
{ 
    enum {value = 0}; 
    template <typename T> 
    static inline void set(T& tup, int l_item) 
    { 
     typedef typename boost::tuples::element<0, T>::type _el_type; 
     get<0>(tup) = atomic_item<0, _el_type>(l_item); 
    }; 
}; 

main(){ 
.... 
/** this is how i try to invoke it */ 
GEN<3>::set(w,1); 
} 

输出:

项目值:1,N-1:2,值:0

函数已被调用一次...

EDIT

有没有办法做一种循环与f or_each或其他任何东西来获得类似的东西:

for_each<range_c<int,0,3> f{operator()(T i)GEN<typename T::value>::set(w,1)}> 

或类似的东西实现所有这些元素的调用?

我特别想有这样的:

GEN<3>::set(w,1); 
GEN<2>::set(w,1); 
GEN<1>::set(w,1); 

在循环。

回答

2

没有递归。递归意味着自称。 set函数在你的代码中确实是而不是这样做。

value声明确实递归(即GEN<N>::value中的GEN<N -1>::value来定义) - 但在一个相当无趣的方式,它只是传播的基本情况数值,0 - 进而,你似乎没有使用此无论如何。

/编辑:这是一个非常简单的例子,以解决您在意见中提出的问题,即实现

GEN<3>::set(w,1); 
GEN<2>::set(w,1); 
GEN<1>::set(w,1); 

的效果其实是很简单的:

template <unsigned N> 
struct GEN { 
    template <typename T> 
    static void set(T& w, int value) { 
     // Do something, e.g.: 
     get<N - 1>(w) = value; 
     // Recurse: 
     GEN<N - 1>::set(w, value); 
    } 
}; 

template <> 
struct GEN<0> { 
    template <typename T> 
    static void set(T&, int) { /* empty */ } 
}; 

现在你可以通过GEN<3>::set(w, 1)调用此代码,它将具有所需的语义。

+0

有没有一种方法可以用for_each或其他东西来做循环: for_each f {operator()(T i)GEN :: set(w,1) }> 或类似的东西? – bua 2011-01-12 21:45:13

1

元编程模板显然确实递归,因为你的代码编译和运行。

您是否期待递归调用set函数?您调用的函数GEN<3>::set不会调用任何其他类的set函数,因此不存在运行时递归。只有编译时递归才能实例化模板。但编译时递归在运行时不会生成输出。