중복되는 코드를 사용하여 c++11

나는'm 현재 프로젝트에서 작업하고 난 다음과 같은 문제입니다.

I have a C++는 방법을 내가 원하는 작업에 두 개의 서로 다른 방법:

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

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

고 싶지 않을 복제 내 코드이기 때문에 실제 기능은 더 이상. 문제는 나가지 않아야 어떤 상황에서 추가 실행 시간을 프로그램을 때 MyFunction 라고 대신 MyFunctionWithABonus. 그것이 왜 나는 그냥 부 매개 변수는 체크인 C++비교입니다.

내 생각했을 것을 사용하여 C++템플릿을 거의 복제 내 코드,하지만 나는't 의 방법을 생각 하고 있는지't 추가 실행 시간 그리고 난't 이 중복되는 코드입니다.

나는'm 지 전문가와 함께 템플릿 그래서 내가 누락 될 수 있습니다 무언가이다.

어떤 당신의 아이디어가 있습니까? 나는 불가능에서는 C++11?

질문에 대한 의견 (9)

같은 것을 할 것입니다 잘:

template
void MyFunction()
{
  foo();
  bar();
  if (bonus) { doBonusStuff(); }
  foobar();
}

통화를 통해 그것:

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

"못생긴"템플릿 수 있는 모든 피를 추가하여 몇 가지 좋은 포장지 기능:

void MyFunctionAlone() { MyFunction(); }
void MyFunctionBonus() { MyFunction(); }

을 찾을 수 있습니다 몇 가지 좋은 정보에는 기술. 즉,"오래 된"지만,기술 그 자체에 머물이 완전히 옳습니다.

제공하는 당신은에 액세스할 수 있는 좋은 C++17 컴파일할 수도 있습한 기술을 사용해constexpr 을 사용하는 경우,다음과 같다:

template 
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();
}
해설 (16)
해결책

와 함께 템플릿 및 lambda 한 작업을 수행할 수 있습니다:

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

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

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

또는 다른을 만들 수 있습접두사접미사기능이 있습니다.

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

void suffix()
{
    foobar();
}

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

void MyFunctionWithABonus()
{
    prefix();
    doBonusStuff();
    suffix();
}
해설 (7)

주어진 일부 의견의 OP 는 관련 디버깅,여기's 버전을 호출하는doBonusStuff()디버그 빌드에 대한,하지만 릴리스 구축(정의하는NDEBUG):

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

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

사용할 수도 있습니다assert크로하려면 체크인 상태이고 실패할 경우 false(에 대해서만 디버그 빌드;릴리스 빌드를 수행하지 않습니다 check).

주의 경우doBonusStuff()가 부작용으로,이러한 부작용이 존재하지 않 릴리스에서 구축하고 있습을 무효로 만들어진 가정 코드입니다.

해설 (4)

여기에 약간의 변형에 Jarod42's 을 사용하여 응답 앞 그래서 손님을 제공할 수 있는 하나 이 보너스 기능:

void callBonus() {}

template
void callBonus(F&& f) { f(); }

template 
void MyFunction(F&&... f)
{
  foo();
  bar();
  callBonus(std::forward(f)...);
  foobar();
}

전화 코드:

MyFunction();
MyFunction(&doBonusStuff);
해설 (0)

다른 버전만 사용하여 템플릿 및 없 리다이렉션 기능을,이후 말라고 했't 원하는 모든 런타임 오버헤드가 발생합니다. 로 fas 으로 I'm 관심이 증가 컴파일시:


#include 

using namespace std;

void foo() { cout 
해설 (3)

당신이 사용할 수 있꼬리표를 파견고 간단한 과부하 기능:

struct Tag_EnableBonus {};
struct Tag_DisableBonus {};

void doBonusStuff(Tag_DisableBonus) {}

void doBonusStuff(Tag_EnableBonus)
{
    //Do bonus stuff here
}

template MyFunction(Tag bonus_tag)
{
   foo();
   bar();
   doBonusStuff(bonus_tag);
   foobar();
}

이것은 쉽게 읽기/해,확장될 수 있습니다 땀이(그리고 보일러하면절-추가하여 더 많은 태그),그리고 물론을 떠날 것이 없 runtime 합니다.

호출하는 구문에 그것이 매우 친절로 그것입니다,하지만 물론 수 있는 포장으로 바닐라 전화:

void MyFunctionAlone() { MyFunction(Tag_DisableBonus{}); }
void MyFunctionBonus() { MyFunction(Tag_EnableBonus{}); }

태그를 파견이 널리 사용되는 일반적인 프로그래밍 기법,여기](https://arne-mertz.de/2016/10/tag-dispatch/)는 좋은 게시물에 대한 기본입니다.

해설 (0)