jeudi 13 juillet 2017

Recursive template function iterating over several template parameters

I wrote a variadic template which is executing a functor F exactly N times and accumulating the result. Now I wonder how to make this template able to process a variable amount of index (template) parameters currently named id and in the desired functor x, y, z.

What I have in mind was a functor like below which is executed as if you call it three for loops. I also wonder whether it could be solved by argument lists.

struct 3DFunctor {
    template <int x, int y, int z>
    static int run() {
        return x*y*z;
    }
};

Desired behavior should be something like:

accum_for<3,3,3>::get<3DFunctor>();

3DFunctor::run<0,0,0>(/*args ...*/) +
3DFunctor::run<0,0,1>(/*args ...*/) +
3DFunctor::run<0,0,2>(/*args ...*/) +
3DFunctor::run<0,1,0>(/*args ...*/) +
3DFunctor::run<0,1,1>(/*args ...*/) +
3DFunctor::run<0,1,2>(/*args ...*/) +
// ..

Example:

#include <iostream>
#include <string>

struct F {
    template <int id>
    static int run(int val) {
        return id * val;
    }
};

template<unsigned int n>
struct accum1d_for {
    template <class Funct, class ... ArgTypes>
    static auto get(ArgTypes ... args) -> decltype(Funct::template run<0>(args ...)) {
        return (
            accum1d_for<n-1>::template get<Funct>(args ...) + 
            Funct::template run<n>(args ...)
        );
    }
};

template<>
struct accum1d_for<0> {
    template <class Funct, class ... ArgTypes>
    static auto get(ArgTypes ... args) -> decltype(Funct::template run<0>(args ...)) {
        return static_cast<decltype(Funct::template run<0>(args ...))>(0);
    }
};

int main()
{
    std::cout << accum1d_for<10>::get<F>(2.f) << std::endl; 
}

Aucun commentaire:

Enregistrer un commentaire