Search code examples
c++c++17template-meta-programmingtype-traitsvariant

How to make a template function enabled if one of variant's types?


I have some variant using V = std::variant<A, B, C> and some function foo with the prototype void foo(const T&).

And want my function foo to be std::enable_ifed if one of V's types are passed (without indicating them explicitly).

My V will get more and more types in time, because of that, solution like

template<class T,
         typename std::enable_if<
            std::is_same_v<T, A> || std::is_same_v<T, B> || std::is_same_v<T, C>,
            int>::type = 0>
void foo(const T&);

is not acceptable.

Here is a boost solution.

Is it possible to implement the logic for std::variant?

Ideally, the type trait should look like is_one_of_variants_types<V, T>.


Solution

  • template <typename, typename>
    constexpr bool is_one_of_variants_types = false;
    
    template <typename... Ts, typename T>
    constexpr bool is_one_of_variants_types<std::variant<Ts...>, T>
        = (std::is_same_v<T, Ts> || ...);
    
    template <typename T>
    auto foo(const T&)
        -> std::enable_if_t<is_one_of_variants_types<V, T>>;
    

    DEMO