Search code examples
c++templatesc++17variadic-templatestype-traits

How to generalize a template specialization for any variadic template type?


I have the following type function to calculate whether some type T is part of the list of types in an std::tuple:

template<typename T, typename Tuple>
struct IsInTuple;

template<typename T, typename ...Ts>
struct IsInTuple<T, std::tuple<Ts...>>
{
  static constexpr bool value = std::disjunction_v<std::is_same<T, Ts>...>;
};

My question is, is it possible to generalize this function for any variadic template type taking a variadic list of types so that it not only works for std::tuple's, but for example also for std::variant's?


Solution

  • Is it possible to generalize this function for any variadic template type taking a variadic list of types so that it not only works for std::tuples, but for example also for std::variants?

    Yes, you can. Just use template template parameter to generalize the type traits.

    template<typename T, typename Class> struct IsInTypeList;
    
    template<typename T
           , template<typename...> class Class, typename... Ts>
    struct IsInTypeList<T, Class<Ts...>>
    {
        static constexpr bool value = (std::is_same_v<T, Ts> || ...);
                                // or std::disjunction_v<std::is_same<T, Ts>...>;
    };
    
    // Example usage
    static_assert(IsInTypeList<int, std::tuple<int, float, double>>::value, "int is not in the tuple");
    static_assert(!IsInTypeList<char, std::tuple<int, float, double>>::value, "char is in the tuple");
    static_assert(!IsInTypeList<char, std::variant<int, float, double>>::value, "char is in the variant");
    

    See live demo