Search code examples
c++templatesc++14variadic-templatestemplate-templates

Bool trick and template template parameters


Consider the bool trick to check if a bunch of types are all the same type:

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;

As an example, one can use it as it follows to check that all the parameters are int values:

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

Is there any way to use it with specializations of a given template template parameter?
As an example, with the following code:

template<typename> struct S {};

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

The allOf variable should be defined as:

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

And I would like to check that each T in Types is a specialization of the form S<U>, no matter of what is U.

Is it possible?


Solution

  • What about as follows ?

    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;