Reputation: 2312
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.
Upvotes: 4
Views: 397
Reputation: 96241
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);
}
Upvotes: 1
Reputation: 3031
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)
{
}
Upvotes: 2
Reputation: 47620
You may use something like that.
for(int j = 0; j < 10; ++j) { // always increases
int i = var ? j : 10 - 1 - j;
//go
}
Upvotes: 1
Reputation: 211590
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.
Upvotes: 4
Reputation: 48267
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.
Upvotes: 3