Duplicate code using c++11

I'm currently working on a project and I have the following issue.

I have a C++ method that I want to work in two different ways :

void MyFunction()
{
  foo();
  bar();
  foobar();
}

void MyFunctionWithABonus()
{
  foo();
  bar();
  doBonusStuff();
  foobar();
}

And I would like not to duplicate my code because the actual function is much longer. The issue is I must not under any circumstance add execution time to the program when MyFunction is called instead of MyFunctionWithABonus. That is why I cannot just have a boolean parameter that I check with a C++ comparison.

My idea would have been to use C++ templates to virtually duplicate my code, but I can't think of a way of doing in which I don't have additional execution time and I don't have to duplicate the code.

I'm not an expert with templates so I may be missing something.

Does any of you have an idea? Or is that just impossible in C++11?


With template and lambda, you may do:

template <typename F>
void common(F f)
{
  foo();
  bar();
  f();
  foobar();
}

void MyFunction()
{
    common([](){});
}

void MyFunctionWithABonus()
{
  common(&doBonusStuff);
}

or else you can just create prefix and suffix function.

void prefix()
{
  foo();
  bar();
}

void suffix()
{
    foobar();
}

void MyFunction()
{
    prefix();
    suffix();
}

void MyFunctionWithABonus()
{
    prefix();
    doBonusStuff();
    suffix();
}

Something like that will do nicely:

template<bool bonus = false>
void MyFunction()
{
  foo();
  bar();
  if (bonus) { doBonusStuff(); }
  foobar();
}

Call it via:

MyFunction<true>();
MyFunction<false>();
MyFunction(); // Call myFunction with the false template by default

The "ugly" template can be all avoided by adding some nice wrappers to the functions:

void MyFunctionAlone() { MyFunction<false>(); }
void MyFunctionBonus() { MyFunction<true>(); }

You can find some nice informations on that technique there. That is an "old" paper, but the technique in itself stay totally right.

Provided you have access to a nice C++17 compiler you can even push further the technique, by using the constexpr if, like that:

template <int bonus>
auto MyFunction() {
  foo();
  bar();
  if      constexpr (bonus == 0) { doBonusStuff1(); }
  else if constexpr (bonus == 1) { doBonusStuff2(); }
  else if constexpr (bonus == 2) { doBonusStuff3(); }
  else if constexpr (bonus == 3) { doBonusStuff4(); }
  // Guarantee that this function will not compile
  // if a bonus different than 0,1,2,3 is passer
  else { static_assert(false);}, 
  foorbar();
}

Given some of the comments the OP has made regarding debugging, here's a version that calls doBonusStuff() for debug builds, but not release builds (that define NDEBUG ):

#if defined(NDEBUG)
#define DEBUG(x)
#else
#define DEBUG(x) x
#endif

void MyFunctionWithABonus()
{
  foo();
  bar();
  DEBUG(doBonusStuff());
  foobar();
}

You can also use the assert macro if you wish to check a condition and fail if it is false (but only for debug builds; release builds will not perform the check).

Be careful if doBonusStuff() has side effects, as these side effects will not be present in release builds and may invalidate assumptions made in the code.

链接地址: http://www.djcxy.com/p/15958.html

上一篇: 在asp.net 2中授权问题

下一篇: 使用c ++ 11重复代码