如何通过函数重载避免代码重复
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 A
和piece 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
}
我有一对重载函数:
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 A
和piece 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
}