c++std-variant

Filter repeated types from a variant


I would like to filter repeated types from a std::variant like this:

std::variant<int, double, int, std::string, int> -> std::variant<int, double, std::string>

std::variant<std::string, std::string, int> -> std::variant<std::string, int>

How can this be done?


Solution

  • #include <type_traits>
    #include <variant>
    
    template <typename T, typename... Ts>
    struct filter_duplicates { using type = T; };
    
    template <template <typename...> class C, typename... Ts, typename U, typename... Us>
    struct filter_duplicates<C<Ts...>, U, Us...>
        : std::conditional_t<(std::is_same_v<U, Ts> || ...)
                           , filter_duplicates<C<Ts...>, Us...>
                           , filter_duplicates<C<Ts..., U>, Us...>> {};
    
    template <typename T>
    struct unique_variant;
    
    template <typename... Ts>
    struct unique_variant<std::variant<Ts...>> : filter_duplicates<std::variant<>, Ts...> {};
    
    template <typename T>
    using unique_variant_t = typename unique_variant<T>::type;
    

    DEMO