正在使用类型用模板函数重构switch语句



我正在尝试重构散布在代码库中的几个开关用例语句,这些语句具有以下结构:

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和classE都继承自基类(classBase(。

someFunc和someFunc2初始化模板中的类并使用它。

重构它的潜在方法是什么?或者我应该重构它吗?

我看到了一个hashmap/orderder映射,它会将Model枚举类型映射到类,但我遇到了错误。

例如:

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
}

我得到以下错误:expected primary-expression before '}' token。这是有意义的,因为它期望在初始化映射时引用一个初始化的类。不过这不是我想要的。

关于如何清理这个有什么想法吗?

在与同事交谈并进行了更多研究后,达成的共识是:

  1. switch语句本身是不可重构的
  2. 每个案例中的逻辑都可以重构为一个函数,因为它完全相同

例如

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);
}
}

这遵循DRY原则,但我可以理解为什么这只是成熟前的重构。

最新更新