Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to refactor nested for loop?

I have two similar functions. Both functions contain a nested for -loop. How I can combine these two functions to decrease duplicated code.

The only difference between funcA and funcB is funcB calls func_2 in the loop.

The two functions like below.

void funcA()
{
    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < size; j++)
        {
            func_1();
        }
    }
}

void funcB() 
{
    for (int i = 0; i < size; i++) 
    {
        for (int j = 0; j < size; j++)
        {
            func_1();
            func_2();
        }
    }
}
like image 272
KeKe Avatar asked Dec 03 '22 17:12

KeKe


2 Answers

You could have used variadic templates.

template<class ... FuncTypes>
void funcAB(FuncTypes... Funcs)
{
    for(int i = 0; i < size; ++i) {
        for(int j = 0; j < size; ++j) {
            (Funcs(), ...);
        }
    }
}

Here is how to call the function.

funcAB(&func_1); // if you want to only call func_1
funcAB(&func_1, &func_2) // if you want both to be called
like image 143
Karen Baghdasaryan Avatar answered Dec 20 '22 13:12

Karen Baghdasaryan


Perhaps I am taking it a little too far, but there is no apparent reason for the nested loops (neither func_1() nor func_2() depend on i or j). A straight forward way to pass a callable is the following:

 template <typename F>
 void func(F f) {
      for (int i=0; i < size*size; ++i) f();
 }

and then call either

 func([](){ func_1(); });
 func(&func_1);               // passing function pointer works as well

or

 func([](){ func_1(); func_2(); });

PS: There is a difference between the nested loops and the flat one when size*size can overflow or it is negative. Though passing the callable is orthogonal to that.

like image 24
463035818_is_not_a_number Avatar answered Dec 20 '22 13:12

463035818_is_not_a_number