Reputation: 67
In a function, I have several consecutive for loops with the same code but different initial values for the control variable. The initial values are obtained from inputs to the function. Ie,
void thisFunction( class A a){
//some other code
for (int i = a.x; i != 0; --i){
code
}
for (int i = a.y; i != 0; --i){
code
}
for (int i = a.z; i != 0; --i){
code
}
//some other code
}
Is there any way to condense all the for loops into one loop so that when I make changes to the code within the loop, I won't have to change it for all three loops? An alternative is to write anotherFunction() with the initial values as input, but I need access to local variables in thisFunction().
void anotherFunction(int in){
for (int i = in; i != 0; --i){
code
}
}
So is there another way to condense the loops?
Thank you.
Upvotes: 4
Views: 919
Reputation: 2426
You can use macro
#define ITERATE(_IN) \
{\
for (int _I = (_IN); _I != 0; --_I){\
code \
}\
}\
Then you have access to local variables, and you only have to manage one copy of the code. So, your code becomes
void thisFunction( class A a){
//some other code
ITERATE(a.x)
ITERATE(a.y)
ITERATE(a.z)
//some other code
}
This may become difficult to debug, so you have to make sure first that it works well, before you make a macro of your code
Upvotes: 1
Reputation: 208333
EDIT: In most cases you should avoid doing this, and rather follow MSalter's answer. Just because you can, doesn't mean you should.
I am not sure how good an idea this is, but without any more context, a simple solution could be:
int starts[3] = { a.x, a.y, a.z };
for ( int var = 0; var < 3; ++var ) {
for ( int i = starts[var]; i != 0; --i ) {
// code
}
}
Note that the values of the conditions are obtained once at the beginning of the function, that means that if the object a
changes throughout the first loop, that change will not be visible in the later control loops. If you need that, the solution can be modified to store pointers.
EDIT: There is a comment suggesting the use of the size of the array. I did not add that here not to modify, but anyway, a better way of getting the array size is:
template<typename T, unsigned int N>
inline unsigned int array_size( T (&)[N] ) {
return N;
}
//...
for ( int var = 0; var < array_size(starts); ++i ) {
Upvotes: 7
Reputation: 23324
Using lambda expressions, you could do this:
void thisFunction( class A a)
{
//some other code
auto code = [&] (int i)
{
// your code here
};
for (int i = a.x; i != 0; --i)
code(i);
for (int i = a.y; i != 0; --i)
code(i);
for (int i = a.z; i != 0; --i)
code(i);
}
Upvotes: 2
Reputation: 179799
Your hunch is right - you'll have to refactor your code into a separate function. Local variables of thisFunction
will become arguments to anotherFunction
; often these will be passed by reference .
Upvotes: 9
Reputation: 272487
Not really. The loops will all be running for different numbers of iterations, surely?
The best you can do is factor out as much of the internals as possible, for instance, into a function like you suggested. Alternatively, have the loop outside the function.
To avoid passing in a load of variables independently, you could consider wrapping them in a class or struct.
Update On second thoughts, David Rodriguez's answer suggestion is a pretty good solution!
Upvotes: 0