模板元编程--TypeList算法 -- 去重(去掉重复)

饼干` / 2023-05-11 / 原文

TypeList的数据结构,参考其他文章。

对于一个TypeList类型列表去掉重复的类型,生成一个没有重复的类型:

有以下数据类型:

using list1 = TypeList<char, double, float, long long, int, int>;

其中有两个int,需要去掉一个。

操作步骤是,新建一个空的结构,然后将数据与新结构进行比较,如果存在那么不操作,否则,将数据添加到新的结构中。

这里使用Fold函数,(该函数的实现在以前的文章中有实现),使用模板P参数处理输入的参数,检查是否存在。

是否存在的函数采用Elem函数实现,Elem函数检查列表,与指定的参数是否相同。

template<TL in>
struct unqiue {
    template<TL out,typename T>
    using Append = std::conditional_t<Elem<out, T>::value, out, out::template append<T> >;
    using type = Fold<in, TypeList<>, Append >::type;
};

out参数会带入Fold的第二个参数,T呢会带入in的参数列表,如果Elem检查到in的参数列表在Fold的第二个参数中,那么直接返回Fold的第二个参数,否则将T加入到第二个参数中并返回。

Elem之前的实现:

template<TL In,typename T>
class Elem {
public:
    template<typename T1,typename Y1>
    using Find = std::conditional_t<T1::value, T1, std::is_same<Y1, T> >;
    using type = Fold<In, std::false_type, Find>::type;
public:
    static constexpr bool value = type::value;
};

Fold之前的实现:

template<typename T>
struct Return { using type = T; };

template<TL in,typename Init,template<typename,typename> class P>
struct Fold:Return<Init>{};

template<typename Init,template<typename,typename> class P,typename T,typename... Ts>
struct Fold<TypeList<T,Ts...>,Init,P>:Fold<TypeList<Ts...>,typename P<Init,T>::type,P>{};

TypeList结构:

template<typename T>
concept TL = requires{
    typename T::isTypeList;
    typename T::type;
};

template<typename... Ts>
struct TypeList {

    struct isTypeList{};
    using type = TypeList<Ts...>;
    constexpr static size_t size = sizeof...(Ts);

    // 成员元函数,在列表的尾部添加元素
    template<typename... T>
    using append = TypeList<Ts..., T...>;
    // 成员元函数,在列表的头部添加元素
    template<typename... T>
    using prepend = TypeList<T..., Ts...>;
    // 成员元函数,将该列表转换为其他模板类
    template<template<typename...> typename T>
    using to = T<Ts...>;
};