Consider a hash table that maps the foo operation to a function pointer, member function, or lambda.
Classic C jump table:
#include <unordered_map>
#include <functional>
using namespace std;
typedef float (*OpFn)(float x, float y);
float add(float x, float y) { return x + y; }
float sub(float x, float y) { return x - y; }
float mult(float x, float y) { return x * y; }
float div(float x, float y) { return x / y; }
typedef float (*OperationFn)(float, float);
extern int foo;
float execute(float input_1, float input_2) {
static std::unordered_map<int, OperationFn> optable = {
{1, add},
{2, sub},
{3, mult},
{4, div}
};
auto itor = optable.find(foo);
if (itor != optable.end()) {
return itor->second(input_1, input_2);
}
return 0;
}
C++ jump table using pointer to member functions:
class Foo {
Foo() {
optable = {
{1, &Foo::add},
{2, &Foo::sub},
{3, &Foo::mult},
{4, &Foo::div}
};
}
int foo;
float add(float x, float y) { return x + y; }
float sub(float x, float y) { return x - y; }
float mult(float x, float y) { return x * y; }
float div(float x, float y) { return x / y; }
typedef float (Foo::* FooOp)(float, float);
std::unordered_map<int, FooOp> optable;
float execute(float input1, float input2) {
auto itor = optable.find(foo);
if (itor != optable.end()) {
auto& fn = itor->second;
(this->*fn)(input1, input2);
}
return 0;
};
};
Or map to lambda functions:
float execute(float input_1, float input_2) {
static std::unordered_map<int, std::function<float(float, float)>> optable = {
{1, [](float x, float y) {return x + y; }},
{2, [](float x, float y) {return x - y; }},
{3, [](float x, float y) {return x * y; }},
{4, [](float x, float y) {return x / y; }},
};
auto itor = optable.find(foo);
if (itor != optable.end()) {
return itor->second(input_1, input_2);
}
return 0;
}
In all of your above scenarios you don't have to inline initialize the optable within the function. That can be initialized and stored elsewhere such as a global variable or as a member of a class.