2011-01-12 103 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函數,因此不存在運行時遞歸。只有編譯時遞歸才能實例化模板。但編譯時遞歸在運行時不會生成輸出。