Home > Mobile >  C variable as a template parameter
C variable as a template parameter

Time:01-02

Is it possible to use variable as template parameter without switch or if else statements for each possible value?

enum A {a, b, c, d};
template<A> void f() {/* default */};
template<> void f<A::a>() {/* ... */}
template<> void f<A::b>() {/* ... */}
template<> void f<A::c>() {/* ... */}

void execute(A action) {
   f<action>()
}

I could use switch statement.

void execute(A action) {
    switch (action) {
        case A::a:
            f<A::a>();
            break;
        case A::b:
            f<A::b>();
            break;
        case A::c:
            f<A::c>();
            break;
    }
}

Or I could add function pointers to a map and use this map afterwards.

std::map<A, void(*)()> mp = {
    {A::a, f<A::a>},
    {A::b, f<A::b>},
    {A::c, f<A::c>}
};

void execute(A action) {
    mp[action]()
}

But both of these solutions require me to specify the mapping manually.

Is there a way of calling function based on a variable? Maybe using macro with function definition, or using template metaprogramming.

CodePudding user response:

You can sort-of do what you want, but it only works if the value of action is known at compile-time. i.e.:

#include <stdio.h>

enum A {a, b, c, d};

template<A> void f() {}
template<> void f<A::a>() {printf("f<A::a>() called\n");}
template<> void f<A::b>() {printf("f<A::b>() called\n");}
template<> void f<A::c>() {printf("f<A::c>() called\n");}

template<A action> void execute() {
   f<action>();
}

int main(int, char**)
{
   constexpr A actionA = A::a;
   constexpr A actionB = A::b;
   constexpr A actionC = A::c;

   execute<actionA>();
   execute<actionB>();
   execute<actionC>();

   return 0;
}

.... yields this output:

$ g   temp.cpp -std=c  11
$ ./a.out 
f<A::a>() called
f<A::b>() called
f<A::c>() called

If you don't/can't know what value action is supposed to have during compilation, then templates are not the right tool for the job, because all the "which-templated-function-should-be-called-here" decisions are made at compile-time.

  • Related