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

时间:2016-12-31 16:38:46

标签: c++ c++11 design-patterns

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

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。

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

  1. A和B属于同一类型,类似于Foo *或可选&lt; Foo&gt;允许测试null

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

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

    Do1(A);
    Do2(A);
    if (B != null) {
      Do1(B);
      Do2(B);
    }
    
  4. 操作顺序很重要。

1 个答案:

答案 0 :(得分: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));
}

以上内容将接受包含指针的原始指针和optional。 您的电话将成为:

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

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

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