在c++中是否有一种方法可以用一个函数来代替两个相似的函数?



下面的代码可以正常编译和运行。但是,对我来说,函数workflow1workflow2中有重复的代码,事实上,唯一的区别是workflow2中增加了参数y,以及对method1/method2的不同调用。有没有办法用一个函数来代替这两个函数?也许有一种方法可以将函数(workflow1workflow2)及其参数作为参数传递给另一个通用函数(例如workflow)?也许这类工作存在一些设计模式?

class MyClass
{
public:
void workflow1(int x) {
doThings(); // actually some code more than just one function call
method1(x);
doOtherThings(); // actually some code more than jus one function call
}
void workflow2(int x, int y=1) {
doThings(); // actually some code; the same as in workflow1()
method2(x,y);
doOtherThings(); // actually some code; the same as in workflow1()
}
private:
void doThings() {}
void doOtherThings() {}
void method1(int x) {}
void method2(int x, int y) {}
};

int main()
{
MyClass myClass;
int x = 0;
myClass.workflow1(x);
int y = 2;
myClass.workflow2(x, y);
}

两个选项:

使用lambda方法:

#include <functional>
class MyClass
{
public:
void workflow1(int x) {
workFlowInternal([x, this] {method1(x); });
}
void workflow2(int x, int y = 1) {
workFlowInternal([x, y, this] {method2(x,y); });
}
private:
void workFlowInternal(const std::function<void()> &func) {
doThings();
func();
doOtherThings();
}

void doThings() {}
void doOtherThings() {}
void method1(int x) {}
void method2(int x, int y) {}
};

或者使用指向成员函数的指针:

class MyClass
{
public:
void workflow1(int x) {
workFlowInternal(&MyClass::method1, x, 0);
}
void workflow2(int x, int y = 1) {
workFlowInternal(&MyClass::method2, x, y);
}
private:
void workFlowInternal(void(MyClass::* func)(int, int), int x, int y) {
doThings();
(this->*func)(x,y);
doOtherThings();
}

void doThings() {}
void doOtherThings() {}
void method1(int x, int ignored=0) {}
void method2(int x, int y) {}
};

你可以直接使用std::optional:

#include <optional>
class MyClass
{
public:
void workflow(int x, std::optional<int> y = {}) {
doThings();
if (!y) method1(x);
else method2(x, *y);
doOtherThings();
}
private:
void doThings() { }
void doOtherThings() { }
void method1(int x) {  }
void method2(int x, int y) { }
};
int main() {
MyClass myClass;
int x = 0;
myClass.workflow(x);
int y = 2;
myClass.workflow(x, y);
}

演示。

你可以这样写一个模板化的函数:

template <bool workflow1>
void Workflow(int x, int y=1)
{
doThings();
if constexpr (workflow1)
{
method1(x);
}
else
{
method2(x, y);
}
doOtherThings();
}
int main()
{
int x = 0;
Workflow<true>(x);
int y = 2;
Workflow<false>(x, y);
}

if constexpr语句是在编译时决定的,因此这将生成两个不同的函数,但您不必重写相同的代码。如果需要支持两种以上的类型,可以将模板参数从bool更改为enum或其他类型。

相关内容

  • 没有找到相关文章