代码之家  ›  专栏  ›  技术社区  ›  bartop

具有唯一类型的变体

  •  3
  • bartop  · 技术社区  · 4 年前

    在写一个cpp库的时候,我有可能 std::variant std::variant<int, double, int, std::string, int> . 它可能在某些场合有用,但在我的图书馆的情况下,我觉得这是不必要的。所以我想过滤如下类型的重复:

    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>

    怎么能做到?

    2 回复  |  直到 4 年前
        1
  •  4
  •   Piotr Skotnicki    4 年前
    #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

        2
  •  4
  •   Barry    4 年前

    Boost.Mp11 ,这是一个短的一行(一如既往):

    using V1 = mp_unique<std::variant<int, double, int, std::string, int>>;
    // V1 is std::variant<int, double, std::string>
    
    using V2 = mp_unique<std::variant<std::string, std::string, int>>;
    // V2 is std::variant<std::string, int>