I am trying to refactor several switch-case statements littered across the code base that have the following structure:
enum Model {
a = 1, b = 2, c = 3, d = 4, e = 5
};
function computeVal(Model m, int param1, int param2, int param3){
Eigen::MatrixXd val, val2;
swtich(m) {
case Model::a:
val = someFunc<classA>(param1, param2, param3);
val2 = someFunc2<classA>(param1, param2, param3);
// some more common logic
case Model::b:
val = someFunc<classB>(param1, param2, param3);
val2 = someFunc2<classB>(param1, param2, param3);
// some more common logic
case Model::c:
val = someFunc<classC>(param1, param2, param3);
val2 = someFunc2<classC>(param1, param2, param3);
// some more common logic
case Model::d:
val = someFunc<classD>(param1, param2, param3);
val2 = someFunc2<classD>(param1, param2, param3);
// some more common logic
default:
val = someFunc<classE>(param1, param2, param3);
val2 = someFunc2<classE>(param1, param2, param3);
// some more common logic
}
}
classA, classB, classC, classD, and classE all inherit from a base class (classBase).
someFunc and someFunc2 initialize the class in the template and use it.
What is a potential way to refactor this? Or should I even be refactoring this?
I was looking at a hashmap / unordered map which would map the Model enum type to the class but I am running into errors.
e.g.:
function computeVal(Model m, int param1, int param2, int param3) {
std::unordered_map<int, classBase*> modelMap = {
{Model::a, classA},
{Model::b, classB},
{Model::c, classC},
...
};
val = someFunc<modelMap[m]>(param1, param2, param3);
val2 = someFunc2<modelMap[m]>(param1, param2, param3);
// some common logic
}
I get the following error: expected primary-expression before '}' token
. Which makes sense since it expects a reference to an initialized class when initializing the map. Thats not what I want here though.
Any ideas on how to clean this up?
After talking with a co-worker and doing some more research - the consensus was:
e.g.
template<class LL>
function commonLogic(int param1, int param2, int param3){
LL someClass();
val = someFunc<someClass>(&someClass, param1, param2, param3);
val2 = someFunc2<someClass>(&someClass, param1, param2, param3);
// some more common logic
}
function computeVal(Model m, int param1, int param2, int param3){
Eigen::MatrixXd val, val2;
swtich(m) {
case Model::a:
computeVal<classA>(param1, param2, param3);
case Model::b:
computeVal<classB>(param1, param2, param3);
case Model::c:
computeVal<classC>(param1, param2, param3);
case Model::d:
computeVal<classD>(param1, param2, param3);
default:
computeVal<classE>(param1, param2, param3);
}
}
This follows the DRY principle but I can see why this would just be pre-mature refactoring.