Home > database >  An elegant approach to comparing many int variables to a value - C
An elegant approach to comparing many int variables to a value - C

Time:07-28

Of the two current answers, I have chosen the one using the range based for loop as it better addressed my first requirement which is to avoid being lengthy. The answer with the variadic template is interesting (and I will try it out!) but lengthier than I would like (since I want everything done inside the same function I mentioned with the variables).

If anyone else comes up with another method, I will still pay attention (even in the far future!) and am always happy to select a possibly better solution ;)


I am using Visual Studio 2017 Professional, C , MFC


I have a strange question which might have no solution

I have a function that comes across several int variables, say I have six in total: int1, int2, ..., int6.

I want to compare each of these values to -1. If any of them == -1, then the void function returns, exiting early.

I know the first idea you may come up with is a lengthy if statement, possibly with several branches like:

if ( (int1 == -1) || (int2 == -1) || ... || (int6 == -1) ) { return;}

or

if (int1 == -1) { return;}
else if (int2 == -1) { return;}
...
else if (int6 == -1) { return;}

Another idea is to push all these ints to a std::vector<int> then iterate through them, comparing each element to -1 with an if clause and returning if there is a match. This is the plan I will fall back to if there is no other solution.

Is there a way to check these values with a more elegant approach that is:

  1. not lengthy
  2. does not use a container such as std::vector
  3. does not use much more memory than either of the two ideas above

Again, I completely understand if there is no method that fits my specifications, and in that case I will go with the std::vector approach. And I do know that at some point I have to bite the bullet and get to comparing the ints but I am interested if there is some other method!

Any help is appreciated, thank you in advance ! :D

CodePudding user response:

You could use a variadic template with a fold expression.

template<typename ...T>
bool any_equal_to_minus_1(T... t) {
    return (... || (t == -1));
}

...
    if (any_equal_to_minus_1(int1, int2, etc)) return;

You could then wrap your function on call side, saving you the typing of variables:

void your_function_real_part(int arg1, int arg2, int arg3);
    
template<typename ...T>
void your_function(T... t) {
    if (any_equal_to_minus_1(t...)) return;
    your_function_real_part(t...);
}

int main() {
    your_function(1, 2, 3);
}

CodePudding user response:

You can use a range based for loop as for example

for ( const auto &item : { v1, v2, v3, v4, v5, v6 } )
{
    if ( item == -1 ) return;
}

or in C 20

for ( int value = -1; const auto &item : { v1, v2, v3, v4, v5, v6 } )
{
    if ( item == value ) return;
}

If you do not want to create copies of the variables in the std::initializer_list then use std::reference_wrapper. As for example

#include <iostream>
#include <functional>
#include <initializer_list>


int main()
{
    int v1 = -1, v2 = -2, v3 = -3, v4 = -4, v5 = -5, v6 = -6;

    for ( auto item : { std::ref( v1 ), std::ref( v2), std::ref( v3 ),
                        std::ref( v4 ), std::ref( v5 ), std::ref( v6 ) } )
    {
        if ( item == -1 )
        {
            std::cout << "There is element with the value -1\n";
            break;
        } 
    }
}
  • Related