Domanda

I have a code that looks something like this:

bool var = some condition...
if( var )
{
     for( int i=0; i<10; ++i )
     {
         //execute some code ...
     }
}
else
{
     for( int i=9; i>=0; --i )
     {
         //execute some other code...
     }
}

However, the code that needs to be executed inside the for loop is almost entirely identical, and so I don't want to write it twice. I know I can do something like this:

bool var = some condition...
for( int i = (var ? 0 : 9 ); (var ? i<10 : i>=0 ); (var ? ++i : --i ) )
{
    //Execute my code
}

But this is a really un-elegant solution.

Is there a short, more elegant way of doing this? I checked std::iterator but I don't think it's what I need.

È stato utile?

Soluzione

You're focusing on the wrong problem here. If you have a direction flag, don't get all hung up on the iteration variable being literally correct. Just interpret it as required:

for (int i = 0; i < n; ++i)
{
   int j = var ? i : n - 1 - i;

   // j goes from 0..n-1 or n-1..0
}

Unless you're doing billions of these calls, the overhead of the secondary variable will be insignificant.

Altri suggerimenti

You can just break the body of the loop out into a function/method and pass in sufficient context for the operation to occur. If the loop body uses mostly fields on this, making it a method should be fairly easy. Otherwise, you shouldn't need more parameters than the loop currently has.

If you're using C++11, you could implement this as a lambda capturing any necessary info, and call the lambda from within each of the loops (so as not to have a loose function). Using a function or method you can test independently is a good idea, though.

Does the code inside the loop depend on the value of the iterator, and if so, how? You might be able to use some basic math in a clever fashion, like transforming the start/end to always be 1..n, or using abs and negatives. This would leave you with one loop, and moving the body out into a function wouldn't be strictly necessary.

It's smart to want to minimize duplicate code, but that doesn't mean that your solution needs to fit in one line. Just write out the logic in a way that makes sense and is legible. Include comments to explain what you're doring and why.

bool var = some condition...
int start = 0;
int end = 9;
int increment = 1;
if (!var)
{
    // Reverse direction
    start = 9;
    end = 0;
    increment = -1;
}

// Loop (forwards if var; reversed if !var)
for (int i = start; i != end; i += increment)
{
} 

You may use something like that.

for(int j = 0; j < 10; ++j) { // always increases
    int i = var ? j : 10 - 1 - j;
    //go
}

This looks suspiciously like iteration to me, so let's try to write a function that will help us out:

void incr(int& i) { ++i; }
void decr(int& i) { --i; }

template <typename Iter, typename Incr>
void do_work(Iter start, Iter finish, Incr incr)
{
    for(Iter i = start, i != finish; incr(i))
    {
        // Do your code.
    }
}

bool var = some condition...
if( var )
{
    do_work(0, 10, &incr);
}
else
{
    do_work(9, -1, &decr);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top