Avoiding an extensive if statement parenthesis

closed account (E8A4Nwbp)
suppose in your header you had these integers
1
2
3
4
5
6
7
8
9
10
11
        int a = 0;
	int b = 0;
	int c = 0;
	int d = 0;
	int e = 0;
	int f = 0;
	int g = 0;
	int h = 0;
	int i = 0;
	int j = 0;
	int k = 0;


There comes a point in the program where a you want to do something IF they are all above 2. How could you find this, without having to use this method:

if(a >= 2 && b >=2 && ...)
Refactor it into an array, and then do a loop over the array.
@ganado
i was wondering for this would you also be able to use the ASCII table
i was wondering for this would you also be able to use the ASCII table

No. You cannot evaluate a variable name at runtime.

You can avoid a giant if statement by using an array of pointers though:
1
2
3
4
5
int *ptrs[11] = {&a, &b, &c, &d, &e, &f, &g, &h, &i, &j, &k};
bool value = true;
for (int i=0; i<11 && value; ++i) {
    value &&= *ptr;
}

if you need to check 20 things, you must look at all of them, or until you know it can't be true, so in worst case, where the thing will be true, you do have look at all of them. A loop would make it less efficient but shorter code, and its a way to clean it up.

that said, perhaps you have a design flaw. It is rare to have so many variables in a condition, and when that does happen, there are often ways to avoid it if you go all the way back to the source of the problem, but we would need details to help you find such a thing. In a theoretical problem, there isn't any fix, but in the real world, the may be.

you can do extra work somewhere else. EG say you read in a-k one time when the program starts: as you read them in, you can also say, for a boolen value, anylessthan2 |= (a <3) and if that turns true (doing it once for each variable!!) one of them is too small. its extra work when you read them in, but forever after, you know that one of them is < 2 or not. Sometimes this can help, sometimes not. If you read them in one time and check this condition hundreds of time, its worth saving the info.

if you stored them in a sorted container, you could check just the smallest one. C++ has a few sorted containers. Sorted containers have a performance hit to do that, so there isn't a free lunch, but it cleans up the code very nicely.
Last edited on
Templates perhaps?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <iomanip>
using namespace std;

template<typename T>
T isGE2(T v) {
  return v >= 2;
}

template<typename T, typename... Args>
T isGE2(T first, Args... args) {
  return first >= 2 && isGE2(args...);
}

int main ( ) {
    int a = 3;
    int b = 4;
    int c = 6;
    int d = 4;
    int e = 3;
    int f = 5;
    int g = 8;
    int h = 2;
    int i = 4;
    int j = 6;
    int k = 7;

    if ( isGE2(a,b,c,d,e,f,g,h,i,j,k) ) {
        cout << "Dawg!" << endl;
    }
}
> IF they are all above 2

1
2
// https://en.cppreference.com/w/cpp/algorithm/min overload (3)  
if( std::min( {a,b,c,d,e,f,g,h,i,j,k} ) > 2 ) { /* ... */ }

If you're really stuck with a long list of source code tokens, it may be beneficial to list them just once and manipulate them with the C preprocessor.

1
2
3
4
5
6
7
8
9
#define ENUMERATE_VARIABLES(O) \ 
  O(a) O(b) O(c) O(d) O(e) /* ... */
#define O(x) int x = 4;
ENUMERATE_VARIABLES(O)
#undef O
// ...
#define O(x) ((x) >= 2) &&
bool const vs_geq_2 = ENUMERATE_VARIABLES(O) true;
#undef O 


The pre-processor exists to eliminate textual repetition. It should be treated as a last resort.
Last edited on
closed account (E8A4Nwbp)
I believe I'll go with either @JLBorgess or @salem c 's method, I've not learned about template in c++, is it quite substantial?

Last edited on
I've not learned about templates in c++, is it quite substantial?

Yes, pretty substantial. Templates are the basis for the C++'s generic programming support. :)
Last edited on
I can't say this enough: all the tricks to pretty it up don't change the fact that you still have to check all the values. All you do is hide the syntax, or move it. Most of the suggestions will give a (microscopic but present) performance hit somewhere. Many of these ideas would confuse the reader "what the heck did he do that for" code (keep this in mind: if you are doing screwy things ONLY to avoid explicit, easy to grok but lengthy syntax, you are usually annoying your reader/peers).

you don't need a template. A normal class can be used to do this.

Its a fun exercise, but I personally would just use the large if statement.

You say you plant to 'go with' an idea, which implies you have a use-case. If you care to explain what you are really trying to accomplish, it would help (I still favor that you may have a design issue that can be nipped in the bud).
Last edited on
It's important to weigh the cost of being clever against the cost of repetition (the obvious solution). One danger with the long condition is that you'll forget to check one of those unrelated variables.

This definitely varies based on the code, but typically, being clever isn't worth it.

If you care to explain what you are really trying to accomplish, it would help
I agree completely. Don't pose XY problems: http://xyproblem.info .
Last edited on
Definitely. If you actually have 11 distinct objects, each with a purpose, then simply putting them in some temporary list to do an operation on them is unnecessary. Because they supposedly have purpose outside of just being an element in a list, which is why they were important enough to be declared as separate variables in the first place.

Without a real example, with real data, it's harder to give better advice.
closed account (E8A4Nwbp)
If you care to explain what you are really trying to accomplish, it would help
I'm making the game of Col https://en.wikipedia.org/wiki/Col_%28game%29
and I am using integers to ensure each sector is selected, to see that the game has ended.(sector a, sector b etc )

salem c wrote:

T isGE2(T first, Args... args) {
return first >= 2 && isGE2(args...);
Sorry, where args is what?
Last edited on
So rather than a,b,c, what you really meant was s1,s2,s3,s4,...

At which point, what you should have been using is a vector of n elements, not n discrete variable names.

A vector would naturally expand to fit the size of the game.
If you wanted a different sized game, you're looking at editing lots of code.

Then you could write
1
2
bool checkForGE2(std::vector<int> &foo ) {
}


> Sorry, where args is what?
Look up "c++ variadic templates"

Topic archived. No new replies allowed.