gpt4 book ai didi

c++ - 当两个功能非常相似时,如何避免复制和粘贴?

转载 作者:行者123 更新时间:2023-12-03 22:17:48 26 4
gpt4 key购买 nike

我经常遇到结构和逻辑相同但有一些差异的方法,我找不到不重复自己的适当方法。

例如 :

void ChannelSelection::selectAlmostOkChannels(int currentInkId)
{
bool selected = true;
foreach (auto report, m_reports) {
if (report.scoreByInk.find(currentInkId) != report.scoreByInk.end()) {
auto tmpStatus = Assessment::getStatusFromScore(report.scoreByInk.value(currentInkId));
if (tmpStatus == Assessment::Ok)
selected = false;
else if (tmpStatus == Assessment::NotOk)
m_autoSelection[report.name].setSelected(currentInkId, false);
}
}
m_currentSelection.insert(currentInkId, selected);
}

void ChannelSelection::selectNotOkChannels(int currentInkId)
{
bool selected = true;
foreach (auto report, m_reports) {
if (report.scoreByInk.find(currentInkId) != report.scoreByInk.end()) {
auto tmpStatus = Assessment::getStatusFromScore(report.scoreByInk.value(currentInkId));
if (tmpStatus == Assessment::Ok || tmpStatus == Assessment::AlmostOk)
selected = false;
}
}
m_currentSelection.insert(currentInkId, selected);
}

如您所见,这两个函数非常相似(只有内部 if 不同)。我怎样才能很好地删除这段代码中的重复?

我想到的解决方案之一是使用仿函数,例如:

void ChannelSelection::selectChannels(int currentInkId, std::function<bool()> fn)
{
bool selected = true;
foreach (auto report, m_reports) {
if (report.scoreByInk.find(currentInkId) != report.scoreByInk.end()) {
auto tmpStatus = Assessment::getStatusFromScore(report.scoreByInk.value(currentInkId));
selected = fn();
}
}
m_currentSelection.insert(currentInkId, selected);
}


调用者负责实现仿函数。有没有没有这个问题的替代方案?

最佳答案

您不必将参数化 selectChannels上市。它可以是 selectAlmostOkChannels 的私有(private)实现细节和 selectNotOkChannels , 你的公共(public)函数。
selectChannels甚至可以实现为函数模板,使生成的代码相当于手写“复制粘贴”的版本,没有代码重复的维护负担

template<typename SelectFunction>
void ChannelSelection::selectChannels(int currentInkId, SelectFunction selectFn)
{
bool selected = true;
foreach (auto report, m_reports) {
if (report.scoreByInk.find(currentInkId) != report.scoreByInk.end()) {
auto tmpStatus = Assessment::getStatusFromScore(report.scoreByInk.value(currentInkId));
selected = selectFn(tmpStatus);
/* fill in */
}
}
m_currentSelection.insert(currentInkId, selected);
}

void ChannelSelection::selectAlmostOkChannels(int currentInkId)
{
selectChannels(currentInkId, [] (auto tmpStatus) -> bool {
return /* fill in */;
});
}

void ChannelSelection::selectNotOkChannels(int currentInkId)
{
selectChannels(currentInkId, [] (auto tmpStatus) -> bool {
return /* fill in */;
});
}

您可能已经被告知模板需要在标题中,但这实际上并不是全部!模板定义需要在实例化的地方可见。由于您的模板仅用于成员函数的私有(private)实现,因此您的模板定义可以在实现两个成员函数的同一个文件中

关于c++ - 当两个功能非常相似时,如何避免复制和粘贴?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58064061/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com