Reputation: 581
While experimenting with variadic templates I came to a point where it would be useful to make kind of reduction of trait values to one final value via some operation. The use-case for me is:
constexpr bool and(bool lhs, bool rhs){return lhs && rhs;}
struct Foo
{
template<
typename ...Ts>
Foo(
Ts&&... args)
noexcept(TraitReduction<std::is_nothrow_move_constructible, and, Ts...>::value)
{/*...*/}
}
The problem is that the STL traits are all single template typed. My current working solution is:
template<
template<typename> class TraitT,
bool (*Operator)(bool,bool),
typename T1,
typename ...Ts>
struct TraitReduction
{
static bool const value = TraitT<T1>::value;
};
template<
template<typename> class TraitT,
bool (*Operator)(bool,bool),
typename T1,
typename T2,
typename ...Ts>
struct TraitReduction<
TraitT,
Operator,
T1,
T2,
Ts...>
{
static bool const value = (*Operator)(
TraitT<T1>::value,
TraitReduction<TraitT, Operator, T2, Ts...>::value);
};
My question is if the STL gives some standardized (probably more convenient) solutionfor that task? And of course I would be happy to here some comments on my current solution, what is bad or what could be better.
Upvotes: 1
Views: 339
Reputation: 217398
Your solution is linear in term of instantiations (and without the advantage of short-circuit)
You may do it in less instantiations (and still without short-circuit)
template <bool...> struct bools{};
template <template <typename> Trait, typename ... Ts>
struct all_of : std::is_same<bools<true, Trait<Ts>::value...>,
bools<Trait<Ts>::value..., true>> {};
You may use std::conjunction
which is linear, but with short-circuit.
c++17 and folding expression has nice syntax, has less instantiations (but without short-circuit (for instantiation)):
(Trait<Ts>::value && ...)
Upvotes: 3