Bool 技巧和模板模板参数

Bool trick and template template parameters

考虑使用 bool 技巧来检查一堆类型是否都是同一类型:

template<typename Type, typename... Types>
static constexpr bool allOf = std::is_same<
    std::integer_sequence<bool, true, std::is_same<Type, Types>::value...>,
    std::integer_sequence<bool, std::is_same<Type, Types>::value..., true>
>::value;

举个例子,可以如下使用它来检查所有参数是否都是int值:

template<typename... Args>
void f(Args&&... args) {
    static_assert(allOf<int, Args...>, "!");
    // ...
}

有什么方法可以将它与给定模板模板参数的特化一起使用吗?
例如,使用以下代码:

template<typename> struct S {};

template<typename... Args>
void f(Args&&... args) {
    static_assert(allOf<S, Args...>, "!");
    // ...
}

allOf 变量应定义为:

template<template<typename> class Type, typename... Types>
static constexpr bool allOf = ???;

而且我想检查 Types 中的每个 T 都是 S<U> 形式的特化,无论 U.[=20 是什么=]

可能吗?

下面呢?

template <typename>
struct S
 { };

template <template <typename> class, typename>
struct isS
 { static constexpr bool value { false } ; };

template <template <typename> class S, typename U>
struct isS<S, S<U>>
 { static constexpr bool value { true } ; };

template<template<typename> class Type, typename... Types>
static constexpr bool allOf = std::is_same<
    std::integer_sequence<bool, true, isS<Type, Types>::value...>,
    std::integer_sequence<bool, isS<Type, Types>::value..., true>
>::value;

我们只需要检查专业化:

template <class T, template <class...> class Z>
struct isZ : std::false_type { };

template <class... Args, template <class...> class Z>
struct isZ<Z<Args...>, Z> : std::true_type  { };

以及 allOf 的更通用的实现:

template <bool... bs>
using allOf = std::is_same<
    std::integer_sequence<bool, true, bs...>,
    std::integer_sequence<bool, bs..., true>>;

有了那个:

static_assert(allOf<isZ<decay_t<Args>, S>::value...>::value, "!");