参考博文:

#include<bits/stdc++.h>
using namespace std;
template<typename...>struct TypeList;
template<typename Head,typename...Tails>
struct TypeList<Head,Tails...>{
    using head=Head;
    using tails=TypeList<Tails...>;
};
template<>struct TypeList<>{};
template<typename TList>struct Length;
template<>
struct Length<TypeList<>>{
    static constexpr int value=0;
};
template<typename Head,typename...Types>
struct Length<TypeList<Head,Types...>>{
    static constexpr int value=Length<TypeList<Types...>>::value+1;
};
template<typename TList,unsigned int index>struct TypeAt;
template<typename Head,typename...Args>
struct TypeAt<TypeList<Head,Args...>,0>{
    using type=Head;
};
template<typename Head,typename...Args,unsigned int i>
struct TypeAt<TypeList<Head,Args...>,i>{
    static_assert(i<sizeof...(Args)+1,"i out of range");
    using type=typename TypeAt<TypeList<Args...>,i-1>::type;
};
template<typename TList,typename T>struct IndexOf;
template<typename Head,typename...Tails,typename T>
struct IndexOf<TypeList<Head,Tails...>,T>{
	private:
	    using Result=IndexOf<TypeList<Tails...>,T>;
	public:
	    static constexpr int value=is_same<Head,T>::value?0:
	    	(Result::value==-1?-1:Result::value+1);
};
template<typename T>
struct IndexOf<TypeList<>,T>{
    static constexpr int value=-1;
};
template<typename,typename>struct Append;
template<typename...TList,typename T>
struct Append<TypeList<TList...>,T>{
    using r_type=TypeList<TList...,T>;
};
template<typename T,typename...TList>
struct Append<T,TypeList<TList...>>{
    using r_type=TypeList<T,TList...>;
};
template<typename...TListLeft,typename...TListRight>
struct Append<TypeList<TListLeft...>,TypeList<TListRight...>>{
    using r_type=TypeList<TListLeft...,TListRight...>;
};
template<typename TList,typename T>struct Erase;
template<typename Head,typename...Tails,typename T>
struct Erase<TypeList<Head,Tails...>,T>{
    using r_type=typename Append<Head,typename Erase<TypeList<Tails...>,T>::r_type>::r_type;
};
template<typename...Tails,typename T>
struct Erase<TypeList<T,Tails...>,T>{
    using r_type=TypeList<Tails...>;
};
template<typename T>
struct Erase<TypeList<>,T>{
    using r_type=TypeList<>;
};
template<typename TList,typename T>struct EraseAll;
template<typename Head,typename...Tails,typename T>
struct EraseAll<TypeList<Head,Tails...>,T>{
    using r_type=typename Append<Head,typename EraseAll<TypeList<Tails...>,T>::r_type>::r_type;
};
template<typename...Tails,typename T>
struct EraseAll<TypeList<T,Tails...>,T>{
    using r_type=typename EraseAll<TypeList<Tails...>,T>::r_type;
};
template<typename T>
struct EraseAll<TypeList<>,T>{
    using r_type=TypeList<>;
};
template<typename TList>struct NoDuplicates;
template<>
struct NoDuplicates<TypeList<>>{
    using r_type=TypeList<>;
};
template<typename Head,typename...Tails>
struct NoDuplicates<TypeList<Head, Tails...>>{
	private:
	    using L1=typename NoDuplicates<TypeList<Tails...>>::r_type;
	    using L2=typename Erase<L1,Head>::r_type;
	public:
	    using r_type=typename Append<Head,L2>::r_type;
};
template<typename TList,typename Old,typename New>struct Replace;
template<typename T,typename U>
struct Replace<TypeList<>,T,U>{
    using r_type=TypeList<>;
};
template<typename...Tails,typename T,typename U>
struct Replace<TypeList<T,Tails...>,T,U> {
    using r_type=typename Append<U,TypeList<Tails...>>::r_type;
};
template<typename Head,typename...Tails,typename T,typename U>
struct Replace<TypeList<Head,Tails...>,T,U>{
    using r_type=typename Append<Head,typename Replace<TypeList<Tails...>,T,U>::r_type>::r_type;
};
int main(){
	
	return 0;
}