What's the most C++ way to check if value belongs to certain static set?

  • A+
Category:Languages

Let's say that I want to write something like this (the {1, 3, 7, 42, 69, 550123} set is known before compilation):

int x; ... if (x == 1 || x == 3 || x == 7 || x == 42 || x == 69 || x == 5550123) {   ... } 

The condition looks ugly because we have 9 extra symbols ("|| x ==") for each possible value. How can I rewrite it in a more C++ way?

My best guess is:

int x; ... const std::unordered_set<int> v = {1, 3, 7, 42, 69, 5550123}; if (v.count(x)) {   ... } 

It has O(1) average complexity with some memory and time overhead, but still looks kinda ugly.

 


Edit: I just noticed c++14 tag. Note that my implementation of in relies on C++17. It can be done in C++14 as well using recursion, but that involves much more boilerplate, and a bit slower compilation.

One could use a template to generate a function with a logical operator sequence, such as the one in nvoigt's answer:

template<auto... ts, class T> constexpr bool in(const T& t) noexcept(noexcept(((t == ts) || ...))) {     return ((t == ts) || ...); }  // usage if (in<1, 3, 7, 42, 69, 5550123>(x)) 

That said, hiding the set of magic numbers behind a named function probably makes a lot of sense:

constexpr bool is_magical(int x) noexcept {     return in<1, 3, 7, 42, 69, 5550123>(x); } 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: