如何将可变参数模板参数的特征值减少为一个值?

How to reduce Trait-values of variadic template parameter to one value?

在试验可变参数模板时,我发现通过某种操作将特征值减少到一个最终值会很有用。我的用例是:

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)
    {/*...*/}
}

问题在于 STL 特征都是单一模板类型。 我目前的工作解决方案是:

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);
};

我的问题是,STL 是否为该任务提供了一些标准化(可能更方便)的解决方案?当然,我很乐意在这里对我当前的解决方案发表一些评论,哪些是不好的,哪些可以更好。

你的解决方案在实例化方面是线性的(并且没有短路的优势)

你可以在更少的实例化中做到这一点(并且仍然没有短路)

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>> {};

你可以使用std::conjunction,它是线性的,但有短路。

c++17 和折叠表达式有很好的语法,实例化较少(但没有短路(用于实例化)):

(Trait<Ts>::value && ...)