我目前有以下形式的代码:
Do1(A);
if (B != null) Do1(B);
Do2(A, true);
if (B != null) Do2(B, true);
Do3(A);
if (B != null) Do3(B);
有好几次,我为对象 A 执行某些操作,如果指定了 B,我也会为 B 执行该操作。这意味着我的整个代码都是重复的,我想更改它,但我无法想出一个改进这种模式的好方法。
到目前为止我唯一的想法是这样的
auto doBoth = [&A,&B](function<void(const T&)> f) {
f(A);
if (B != null) f(B);
};
doBoth(&Do1);
auto do2_bind = [](const T& obj) {Do2(obj, true);};
doBoth(do2_bind);
doBoth(&Do3);
但我觉得这会大大降低可读性,并使别人更难理解我的代码,因为有一个非常抽象的 lambda 函数和很多一般的 lambda。
编辑:从答案和评论中我发现我应该做出一些澄清。对于造成的困惑,我深表歉意。
A 和 B 具有相同的类型,类似于 Foo* 或允许测试 null 的可选
我只能使用 C++11 功能
代码块(我在这里缩写为 DoN)可能比单个函数调用更复杂。例如,如果可能是:
Do1(A); Do2(A); if (B != null) { Do1(B); Do2(B); }
其中操作顺序很重要。
最佳答案
您的方法是合理的,但您似乎并不真正需要 std::function
。只是一个接受可调用的模板:
template<typename A, typename B, typename Func>
void do_for_both(A&& a, B&& b, Func&& func)
{
func(std::forward<A>(a));
if(b != nullptr)
func(std::forward<B>(b));
}
上面的代码将接受原始指针和保存指针的可选
。
然后您的调用将变为:
do_for_both(a, b, [](auto&& param){
Do1(param);
});
do_for_both(a, b, [](auto&& param){
Do2(param, true);
});
嗯,上面的将适用于 c++14。但我现在注意到了 c++11 的要求。所以这个答案现在仅供引用。
关于C++ 重复 do-if-do 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41410114/