Search code examples
c++metaprogramming

Can I use metaprogramming to generate a different function for every possible parameter value?


I would like reduce the numbers of parameters passed to a function by creating as many functions as possible parameters combination.

Let's say I have a struct with a few registers :

struct S {
    std::array<int,5> reg;
};

and a function adding some registers together :

void add(S& s, int a, int b){
    s.reg[b] += s.reg[a];
}

Can I use metaprogramming to generate a different function for every possible parameter value ?

That is :

add_0_0(S& s){s.reg[0] += s.reg[0];} // equivalent to add(S& s, 0, 0)
add_0_1(S& s){s.reg[0] += s.reg[1];} // equivalent to add(S& s, 0, 1)
...
add_4_4(S& s){s.reg[4] += s.reg[4];} // equivalent to add(S& s, 4, 4)

I could achieve this using a script and some macros, a bit like this :

for a in {0..4}
do
for b in {0..4}
do
echo "void add_"$a"_"$b"(S& s)"
echo "{"
echo "    s.reg["$b"] += s.reg["$a"];"
echo "}"
done
done

but I thought it could be a good candidate for metaprogramming. Unfortunately I don't know where to start ...


Solution

  • This is, pretty much how template functions work in C++, with the only difference is the actual naming convention used by the "different" functions:

    template<int a, int b>
    void add(S& s){
        s.reg[b] += s.reg[a];
    }
    

    and then:

    add<0,0>(s);
    add<0,1>(s);
    // ...
    add<4,4>(s);
    

    This is fairly basic use of templates in C++. The naming convention might seem a bit awkward the first time it's seen. But, with practice and experience, it won't be long before it becomes natural, and second-nature.

    P.S. There's nothing that immediately stops you from calling

    add<4,5>(s);
    

    and all hell breaking loose. But, with a little bit more work it's possible to produce a compilation error, were that to happen.