0


I try to invoke function void set (...) recursively using metaprogramming.
The problem is that it seems to invokes only once.

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

Output:

item value: 1, N-1: 2, value: 0

function has been invoked only once...

EDIT

is there a way to do kind of loop with for_each or anything else to get something simmilar:

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

or something similar to achieve invoke for all of those elements?

Particularly I'd like to have this:

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

In loop.

2 Answers 2

2

There is no recursion. Recursion means calling yourself. The set function in your code does not do this.

Your value declaration does recurse (i.e. GEN<N>::value is defined in terms of GEN<N -1>::value) – but in a pretty uninteresting way, it just propagates the base case value, 0 – and furthermore you don’t seem to be using this value anyway.

/EDIT: Here’s a very simple example to address the point raised by you in the comments, i.e. to achieve the effect of

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

That’s actually pretty easy:

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 */ }
};

Now you can call this code via GEN<3>::set(w, 1) and it will have the desired semantics.

Sign up to request clarification or add additional context in comments.

4 Comments

is there a way to do kind of loop with for_each or anything else to get: for_each<range_c<int,0,3> f{operator()(T i)GEN<typename T::value>::set(w,1)}> or something simmilar?
@bua: no idea. I’ve never worked with range_c. But I doubt that it works since for_each isn’t expanded at compile time (and as far as I see Boost.MPL doesn’t offer an appropriate mechanism for this). But you can make your code work, you just need to insert the recursive call at the right point (I can’t help you there, I don’t really understand what your code is doing since I don’t know atomic_item.
@Kondrad Now I'd like to achieve GEN<3>::set(w,1); GEN<2>::set(w,1); GEN<1>::set(w,1); in a loop.
ha :D your comment //do something eg. can be changed to my two lines and recursion works ! Thanks mate, I was missing GET<N-1>::set(...) all the time :D
1

The metaprogramming template obviously did recurse since your code compiled and ran.

Were you expecting a recursive call of the set function? The function you called, GEN<3>::set doesn't call the set function of any other class, so there is no run-time recursion. There is only compile-time recursion to instantiate the templates. But compile-time recursion doesn't generate output at run time.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.