How can I rewrite it in a more C++ way?
Suggestion: make a variadic template function for it, make it generic (non only for int
values) and make it constexpr
; this way you can check, the presence of the value in the set, compile time.
You tagged C++14 but I show first the recursive way for C++11, with a recursive case and a ground case
template <typename T>
constexpr bool is_in_list_11 (T const &)
{ return false; }
template <typename T, T t0, T ... ts>
constexpr bool is_in_list_11 (T const & t)
{ return (t == t0) || is_in_list_11<T, ts...>(t); }
Starting from C++14, a constexpr
function can be a lot more complex, so recursion isn't necessary anymore and you can write something as
template <typename T, T ... ts>
constexpr auto is_in_list_14 (T const & t)
{
using unused = bool[];
bool ret { false };
(void)unused { false, ret |= t == ts ... };
return ret;
}
Starting from C++17 you can use also auto
template type and template folding, so (as user2079303 showed before) the function become very very simple
template <auto ... ts, typename T>
constexpr auto is_in_list_17 (T const & t)
{ return ( (t == ts) || ... ); }
The following is a full working example with all versions
#include <iostream>
template <typename T>
constexpr bool is_in_list_11 (T const &)
{ return false; }
template <typename T, T t0, T ... ts>
constexpr bool is_in_list_11 (T const & t)
{ return (t == t0) || is_in_list_11<T, ts...>(t); }
template <typename T, T ... ts>
constexpr auto is_in_list_14 (T const & t)
{
using unused = bool[];
bool ret { false };
(void)unused { false, ret |= t == ts ... };
return ret;
}
template <auto ... ts, typename T>
constexpr auto is_in_list_17 (T const & t)
{ return ( (t == ts) || ... ); }
int main ()
{
constexpr auto b11a { is_in_list_11<int, 1, 3, 7, 42, 69, 5550123>(7) };
constexpr auto b11b { is_in_list_11<int, 1, 3, 7, 42, 69, 5550123>(8) };
constexpr auto b14a { is_in_list_14<int, 1, 3, 7, 42, 69, 5550123>(7) };
constexpr auto b14b { is_in_list_14<int, 1, 3, 7, 42, 69, 5550123>(8) };
constexpr auto b17a { is_in_list_17<1, 3, 7, 42, 69, 5550123>(7) };
constexpr auto b17b { is_in_list_17<1, 3, 7, 42, 69, 5550123>(8) };
std::cout << b11a << ' ' << b11b << std::endl;
std::cout << b14a << ' ' << b14b << std::endl;
std::cout << b17a << ' ' << b17b << std::endl;
}
switch
statement is for. – Adaurdcount(...) > 0
is not as good as e.g.contains(...)
, which will be available in C++20. – Garaldif (x <in> {1, 3, 7, 42, 69, 5550123})
good enough? github.com/klmr/named-operator – Telepathyunordereded_map
/vector
for this. They are highly inefficient for this task (if you have only 6 numbers). – Pluralize