如何通过函数重载避免代码重复

How to avoid code duplication with function overloading

我有一对重载函数:

void func(const std::string& str, int a, char ch, double d) {
    // piece of code A
    sendMsg(str, a, ch, d);
    // piece of code B
}

void func(int a, char ch, double d) {
    // piece of code A
    sendMsg(a, ch, d);
    // piece of code B
}

piece of code Apiece of code B完全一样,唯一不同的是sendMsg.

的参数

有没有办法避免代码重复?

你必须做类似的事情

void codeA() {
    // ...
}

void codeB() {
    // ...
}

void func(const std::string& str, int a, char ch, double d) {
    codeA();
    sendMsg(str, a, ch, d);
    codeB();
}

void func(int a, char ch, double d) {
    codeA();
    sendMsg(a, ch, d);
    codeB();
}

模板可能是一种可能性:

template <typename ... Ts>
auto func(const Ts&... args)
-> decltype(sendMsg(args...), void()) // SFINAE to only allow correct arguments
{
    // piece of code A
    sendMsg(args...);
    // piece of code B
}

但将 // piece of code A 移动到它自己的功能中可能是我的选择。

当然是用仿函数:

template <typename F> void func2(F&& f) {
    // piece of code A
    f();
    // piece of code B
}

用法:

void func(int a, char ch, double d) {
    func2([&](){ sendMsg(a, ch, d); });
}

一点解释: 当您需要使用不同的参数调用完全相同的代码时,当前接受的答案完全没问题。但是,当您需要将任意代码(可能是多段任意代码)“注入”到另一个函数中时,传递临时 lambda 是最好的选择。从概念上讲,seeing/getting 的接收函数是一些抽象的“可调用”对象(事实上,它可以是任何带有 operator (),而不仅仅是 lambda 的对象),它会在适当的时候调用。由于它是一个模板化函数,它将被编译成零开销代码,“就像”实际代码被复制粘贴到那里一样。使用部分只是展示了一个 c++ 语法来创建一个可调用的任意代码(我建议阅读 lambdas 上的语言 references/tutorials 以更好地理解内部结构)。

另一个想法是给str一个默认值:

void func(int a, char ch, double d, const std::string& str = "")
{
    // piece of code A
    if (str.empty()) sendMsg(a, ch, d);
    else sendMsg(str, a, ch, d);
    // piece of code B
}