C ++ The most efficient way to compare a variable with multiple values?

Several times in my program I had to check if a variable was one of many options. for example

if (num = (<1 or 2 or 3>)) { DO STUFF } 

I messed up the "OR", but nothing seems right. I tried

 if (num == (1 || 2 || 3)) 

but he does nothing. Please help! Thanks in advance.

PS I need to distinguish between several groups. For example...

 if (num = (1,2,3)) else if (num = (4,5,6)) else if (num = (7,8,9)) 
+8
c ++ variables comparison if-statement
source share
6 answers

If the values ​​you want to check are small enough, you can create a bit mask for the values ​​you are looking for, and then check if this bit is set.

Suppose you take care of several groups.

 static const unsigned values_group_1 = (1 << 1) | (1 << 2) | (1 << 3); static const unsigned values_group_2 = (1 << 4) | (1 << 5) | (1 << 6); static const unsigned values_group_3 = (1 << 7) | (1 << 8) | (1 << 9); if ((1 << value_to_check) & values_group_1) { // You found a match for group 1 } if ((1 << value_to_check) & values_group_2) { // You found a match for group 2 } if ((1 << value_to_check) & values_group_3) { // You found a match for group 3 } 

This approach is best suited for values ​​that do not exceed the natural size that your processor likes to work with. Usually this will be 64 nowadays, but may vary depending on the specifics of your environment.

+6
source share

Here is the path in C ++ 11 using std :: initializer_list:

 #include <initializer_list> template <typename T> bool is_in(const T& val, const std::initializer_list<T>& list) { for (const auto& i : list) { if (val == i) { return true; } } return false; } 

with this you can:

 if (is_in(num, {1, 2, 3}) { DO STUFF } 

Please note that things like <1 are not possible.

+14
source share

You must perform a comparison with each value. For example.

 if (num == 1 || num == 2 || num == 3) { stuff } 

You might also consider switching and deliberately dropping cases (although I don't think this is the best solution for what you state).

 switch (num) { case 1: case 2: case 3: {DO STUFF} break; default: //do nothing. } 
+4
source share

I had a similar problem and came up with these solutions in C ++ 11:

 template <class T> struct Is { T d_; bool in(T a) { return a == d_; } template <class Arg, class... Args> bool in(Arg a, Args... args) { return in(a) || in(args...); } }; template <class T> Is<T> is(T d) { return Is<T>{d}; } 

Or as an alternative without a recursion completion method. Keep in mind that here the comparison order is undefined and that it does not end earlier if the first match is found. But the code is more compact.

 template <class T> struct Is { const T d_; template <class... Args> bool in(Args... args) { bool r{ false }; [&r](...){}(( (r = r || d_ == args), 1)...); return r; } }; template <class T> Is<T> is(T d) { return Is<T>{d}; } 

So, for both solutions, the code will look like this:

 if (is(num).in(1,2,3)) { // do whatever needs to be done } 
+3
source share

You can define a set of integers, add the desired values ​​to it, and then use the find method to find out if the specified value is in the set

 std::set<int> values; // add the desired values to your set... if (values.find(target) != values.end()) ... 
+2
source share

I needed to do something similar for listings. I have a variable and want to test it against ranges of values.

Here I used the variational function of the template. Note the specialization for the const char* , so is_in( my_str, "a", "b", "c") has the expected result when my_str stores "a" .

 #include <cstring> template<typename T> constexpr bool is_in(T t, T v) { return t == v; } template<> constexpr bool is_in(const char* t, const char* v) { return std::strcmp(t,v); } template<typename T, typename... Args> constexpr bool is_in(T t, T v, Args... args) { return t==v || is_in(t,args...); } 

Usage example:

 enum class day { mon, tues, wed, thur, fri, sat, sun }; bool is_weekend(day d) { return is_in(d, day::sat, day::sun); } 
0
source share

All Articles