Как избежать дублирования - PullRequest
0 голосов
/ 23 февраля 2012

Рассмотрим функции ниже

f(int a[])
{
     ///CODE
     for
      for
       if(a[i] > 0)
       //change i on some condition
     for
        //CODE
        if(a[i] > 0)
    ///CODE

}
f(int a[], int th)
{
     ///CODE
     for
      for
        if(a[i] < th)
       //change i on some condition
     for
        //CODE
        if(a[i] < th)
    ///CODE
}

Итак, у нас есть функция f с оптимизированным огромным телом, несколько строк одинаковы: если (a [i]> 0), я хочу добавить расширение этой функции так, чтобыесли добавлен параметр, эти строки должны измениться на if (a [i]

Первая идея:

f(int a[], int th = -1)
{
     ///CODE
        if(th == -1)
            if(a[i] > 0)...
        else
            if(a[i] < th)...
     ///CODE
}

Я не могу сделать это из-за снижения производительности при представлениидополнительный, если к внутренней петле.Есть ли способ решить ее эффективно и четко, возможно, с помощью шаблонов или макросов?

Ответы [ 2 ]

6 голосов
/ 23 февраля 2012

Вы можете попытаться сделать это функцией-шаблоном, который принимает произвольный предикат. Если предикат прост, как в ваших случаях, вы, вероятно, можете положиться на компилятор, чтобы встроить его, чтобы не было потери эффективности. Вы должны профилировать свою заявку, чтобы убедиться в этом. Код может выглядеть так:

template<class Pred>
void f(int a[], Pred pred) {
 ///CODE
 for
  for
   if(pred(a[i]))
   //change i on some condition
 for
    //CODE
    if(pred(a[i]))
///CODE
}

До C ++ 11 вам приходилось передавать функторы или указатели функций в качестве предикатов, в C ++ 11 вы могли бы использовать лямбда-выражения:

f(data, [](int val){ return val > 0; });
f(data, [th](int val){ return val < th; });
2 голосов
/ 23 февраля 2012

Вы можете передавать функции через аргументы шаблона:

template<bool Cmp(int,int)>
void f(int a[], int th)
{
    //..
    if (Cmp(a[i],th)) {
       //...
    }
    //...
}

Затем вы можете использовать f следующим образом:

bool cmp(int a, int b) { return a < b; }
f<cmp>(...)
...