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++'ish 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);
}