You can try the following:
template <template <typename...> class Pred, typename ...Args> struct check_odd; template <template <typename...> class Pred> struct check_odd<Pred> : std::true_type { }; template <template <typename...> class Pred, typename T> struct check_odd<Pred, T> : Pred<T> { }; template <template <typename...> class Pred, typename T1, typename T2, typename ...Args> struct check_odd<Pred, T1, T2, Args...> { static constexpr bool value = Pred<T1>::value && check_odd<Pred, Args...>::value; };
Using:
static_assert(check_odds<std::is_arithmetic, T1, T2, T3, T4, T5, T6>::value, "Not all odd types are arithmetic.");
Obvious generalization routes parameterize the combiner (currently hardcoded as "AND" or && ) and provide additional predicate parameters.
source share