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.