C++ 实现一个type list 模板,在编译期计算。这个type list主要有构造,列表头类型,列表尾类型,concat操作,去除列表元素重复,获取指定元素,删除指定元素的操作。实现代码贴在下面:
#pragmaonce#include<iostream>#include<typeinfo>namespace type_list {// Step 1: 基础类型列表定义// 定义空列表template<typename...Types>structlist{};// 非空列表的递归定义template<typenameType,typename...Types>structlist<Type, Types...>{using head = Type;using tail = list<Types...>;};// 定义空列表类型using empty_list = list<>;// Step 2: 获取列表头部类型template<typenameTypeList>using head_t =typenameTypeList::head;// 获取列表尾部类型template<typenameTypeList>using tail_t =typenameTypeList::tail;// 构造新列表template<typenameHead,typenameTail>structconstruct;template<typenameHead,typenameTail>using construct_t =typenameconstruct<Head, Tail>::type;template<typenameHead,typename...Types>structconstruct<Head, list<Types...>>{using type = list<Head, Types...>;};///template<typenameTypeList>structsize;// 模板辅助类template<typenameTypeList>constexpr size_t size_v = size<TypeList>::value;//size的模板特化,继承了std::integral_constanttemplate<typename...Types>structsize<list<Types...>>: std::integral_constant<std::size_t,sizeof...(Types)>{};template<classTypeList>constexprbool empty_v =(size_v<TypeList>==0);template<classTypeList>structempty:std::bool_constant<empty_v<TypeList>>{};template<classTypeList>constexprbool empty_s = empty<TypeList>::value;/// 查找模板的制定索引的value//声明一个模板;template<std::size_t Index,classTypeList>structget;template<std::size_t Index,classTypeList>using get_t =typenameget<Index, TypeList>::type;template<std::size_t Index,classTypeList>structget{using type = get_t<Index -1, tail_t<TypeList>>;};template<classTypeList>structget<0, TypeList>{using type = head_t<TypeList>;};/// concattemplate<typenameTypeList1,typenameTypeList2>classconcat;template<typenameT,typenameU>using concat_t =typenameconcat<T, U>::type;template<typename...T,typename...U>classconcat<list<T...>, list<U...>>{public:using type = list<T..., U...>;};// delete specific typetemplate<typenameTypeList,typenameType>classremove_all;template<typenameTypeList,typenameType>using remove_all_t =typenameremove_all<TypeList, Type>::type;template<typenameTypeList,typenameType>classremove_all{public:using head = head_t<TypeList>;using tail = tail_t<TypeList>;using clean_tail = remove_all_t<tail, Type>;using type = std::conditional_t<std::is_same_v<head, Type>, clean_tail, construct_t<head, clean_tail>>;};template<typenameType>classremove_all<empty_list, Type>{public:using type = empty_list;};// get the last typetemplate<typenameTypeList>classlast;template<typenameTypeList>using last_t =typenamelast<TypeList>::type;template<typenameTypeList>classlast{public:using type = last_t<tail_t<TypeList>>;};// 递归终止template<typenameType>classlast<list<Type>>{public:using type = Type;};// distinct list typetemplate<typenameTypeList>classdistinct;template<typenameTypeList>using distinct_t =typenamedistinct<TypeList>::type;template<typenameTypeList>classdistinct{public:using type = construct_t<head_t<TypeList>,distinct_t<remove_all_t<tail_t<TypeList>, head_t<TypeList>>>>;};// 递归终止template<>structdistinct<empty_list>{using type = empty_list;};// print listtemplate<typenameT>voidprint_type(){int status;std::cout <<typeid(T).name()<< std::endl;}// 打印类型列表template<typenameTypeList>structprint_list;template<typenameTypeList>voidprint_list_func(){print_list<TypeList>::print();}// 主模板,递归地打印类型列表template<typenameTypeList>structprint_list{staticvoidprint(){print_type<head_t<TypeList>>();print_list_func<tail_t<TypeList>>();}};// 终止递归的特化版本template<>structprint_list<empty_list>{staticvoidprint(){// 空列表,不打印任何内容}};}// namespace type_list
测试代码
#pragmaonce#include"type_list.h"#include<iostream>usingnamespace std;voidtest_type_list(){//1.define listusing MyList = type_list::list<int,double,char>;using AnotherList = type_list::list<float,int>;using EmptyList = type_list::list<>;//2. get the head and tail type of listusing MyListHead = type_list::head_t<MyList>;using MyListTail = type_list::tail_t<MyList>;static_assert(std::is_same_v<MyList::tail, type_list::list<double,char>>,"MyList head shoud be int");static_assert(std::is_same_v<MyListTail, type_list::list<double,char>>,"MyList head shoud be int");static_assert(std::is_same_v<MyListHead,int>,"MyList head shoud be int");static_assert(std::is_same_v<MyList::head,int>,"MyList head shoud be int");//3. get list sizeconstexpr std::size_t listSize = type_list::size_v<MyList>;std::cout << listSize << std::endl;// 4. emptystatic_assert(type_list::empty_s<EmptyList>,"is empty");static_assert(type_list::empty_v<EmptyList>,"is empty");// 5. get index posusing FirstType = type_list::get_t<1, MyList>;static_assert(std::is_same_v<FirstType,double>,"not equal");// 6.concat listusing ConcatList = type_list::concat_t<MyList, AnotherList>;using ConcatListHead = type_list::head_t<ConcatList>;static_assert(std::is_same_v<ConcatListHead,int>,"head should be int");static_assert(std::is_same_v<ConcatList::head,int>,"head should be int");constexpr std::size_t concat_list_size = type_list::size_v<ConcatList>;cout <<"concat_list_size : "<< concat_list_size << endl;// 6.delete list typeusing RemoveIntList = type_list::remove_all<MyList,int>;static_assert(std::is_same_v<type_list::head_t<RemoveIntList>,int>,"the list head shoud not be int");// 6.delete list typeusing LastType = type_list::last_t<MyList>;static_assert(std::is_same_v<LastType,char>,"the last type should be char");// distinct list typeusing RepeatList = type_list::list<int,double,char,int,double,char,int,int,int>;using DistType = type_list::distinct_t<RepeatList>;std::cout <<"--------------------------"<< endl;type_list::print_list_func<RepeatList>();std::cout <<"--------------------------"<< endl;type_list::print_list_func<DistType>();std::cout <<"--------------------------"<< endl;}