C++重复的do-if-do模式

And*_*s T 2 c++ design-patterns c++11

我目前有以下形式的代码:

Do1(A);
if (B != null) Do1(B);

Do2(A, true);
if (B != null) Do2(B, true);

Do3(A);
if (B != null) Do3(B);
Run Code Online (Sandbox Code Playgroud)

所以好几次,我为对象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);
Run Code Online (Sandbox Code Playgroud)

但我觉得这会大大降低可读性,让人更难理解我的代码,因为有一个非常抽象的lambda函数和一般的很多lambdas.

编辑:从答案和评论我看到我应该做出一些澄清.我为混乱道歉.

  1. A和B属于同一类型,类似于Foo*或可选的<Foo>,它允许测试null

  2. 我只能使用C++ 11功能

  3. 代码块(我在这里简称为DoN)可能比单个函数调用更复杂.例如,如果可能是:

    Do1(A);
    Do2(A);
    if (B != null) {
      Do1(B);
      Do2(B);
    }
    
    Run Code Online (Sandbox Code Playgroud)

操作顺序很重要.

Sto*_*ica 5

你的方法是合理的,但你似乎并不需要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));
}
Run Code Online (Sandbox Code Playgroud)

上面会接受原始指针和optional持有指针的s.您的电话将成为:

do_for_both(a, b, [](auto&& param){
  Do1(param);
});

do_for_both(a, b, [](auto&& param){
  Do2(param, true);
});
Run Code Online (Sandbox Code Playgroud)

好吧,上面的内容适用于c ++ 14.但我现在注意到了c ++ 11的要求.所以这个答案现在只是一个参考.

  • 同意.(尽管用"合理的"代替"正确"也许 - 我们所做的并不是绝对的!) (2认同)