这是昨天和今天写的东西,利用C++的可变模板参数包以及包展开,模式匹配的一些东西做的,感觉用typename...比轮子叔那个List<A,List<B, List<C, D>>>的设计要好看不少。
List有一个很巧妙的继承,只有那么做才能使用类似于List<>::Rest的写法,直接定义成template<typename T, typename... TArgs>List是不行的。
Change这里可以给一个args...换另一个包装,这里感谢lyp菊苣告诉我原来template里还能接着套template,为我自己瞎摸索TML的道路开拓了另一片新天地。
scanf和foldl的原理大致基本相同,但是以我的智商是没法在短时间内把他们统一到一起了。
PrintList似乎只能使用函数来输出了。
写着写着也发现自己的模板元编程的编码和命名风格在不断完善,果然要不停写才能体会到东西。
(话说默认字体大小怎么改啊,13px才好看嘛)
1 template<typename T> 2 struct ListGet; 3 template<typename... TArgs> 4 struct List; 5 6 template<typename T, typename... TArgs> 7 struct ListGet<List<T, TArgs...>> 8 { 9 using First = typename T; 10 using Rest = List<TArgs...>; 11 }; 12 13 template<typename... TArgs> 14 struct List: ListGet<List<TArgs...>> 15 { 16 using Base = ListGet<List<TArgs...>>; 17 using Self = List<TArgs...>; 18 }; 19 20 template<typename T> 21 struct ListIsEmpty; 22 23 template<typename T, typename... TArgs> 24 struct ListIsEmpty<List<T, TArgs...>> 25 { 26 using Result = Bool<false>; 27 }; 28 template<> 29 struct ListIsEmpty<List<>> 30 { 31 using Result = Bool<true>; 32 }; 33 34 template<typename A, template<typename... Args> typename B> 35 struct Change; 36 37 template<template<typename... Args>typename A, template<typename... Args>typename B, typename... Args> 38 struct Change<A<Args...>, B> 39 { 40 using Result = B<Args...>; 41 }; 42 43 template<typename T1, typename T2> 44 struct ListConnect; 45 46 template<typename... TArgs1, typename... TArgs2> 47 struct ListConnect<List<TArgs1...>, List<TArgs2...>> 48 { 49 using Result = typename List<TArgs1..., TArgs2...>; 50 }; 51 template<typename T> 52 struct ListReverse; 53 54 template<typename... TArgs> 55 struct ListReverse<List<TArgs...>> 56 { 57 using Param = typename List<TArgs...>; 58 using Result = typename ListConnect< 59 typename ListReverse< 60 typename Param::Rest 61 >::Result, 62 typename List<typename Param::First> 63 >::Result; 64 }; 65 66 template<typename T> 67 struct ListReverse<List<T>> 68 { 69 using Result = typename List<T>; 70 }; 71 72 template<template<typename ST> typename TApplicative, typename T1> 73 struct ListMap; 74 75 template<template<typename ST> typename TApplicative, typename... TArgs> 76 struct ListMap<TApplicative, List<TArgs...>> 77 { 78 using Param = typename List<TArgs...>; 79 using Result = typename ListConnect< 80 List< 81 typename TApplicative< 82 typename Param::First 83 >::Result 84 >, 85 typename ListMap< 86 TApplicative, 87 typename Param::Rest 88 >::Result 89 >::Result; 90 }; 91 92 template<template<typename ST> typename TApplicative, typename TLast> 93 struct ListMap<TApplicative, List<TLast>> 94 { 95 using Param = typename List<TLast>; 96 using Result = typename List<typename TApplicative<TLast>::Result>; 97 }; 98 99 template<typename TVal, template<typename TArg1, typename TArg2> typename TBinFunc, typename T> 100 struct ListFoldLeft; 101 102 template<typename TVal, template<typename TArg1, typename TArg2> typename TBinFunc, typename... TArgs> 103 struct ListFoldLeft<TVal, TBinFunc, List<TArgs...>> 104 { 105 using Param = List<TArgs...>; 106 using Result = typename ListFoldLeft< 107 typename TBinFunc< 108 TVal, 109 typename Param::First 110 >::Result, 111 TBinFunc, 112 typename Param::Rest 113 >::Result; 114 }; 115 116 template<typename TVal, template<typename TArg1, typename TArg2> typename TBinFunc, typename TLast> 117 struct ListFoldLeft<TVal, TBinFunc, List<TLast>> 118 { 119 using Param = List<TLast>; 120 using Result = typename TBinFunc<TVal, typename Param::First>::Result; 121 }; 122 123 template<typename TVal, template<typename TArg1, typename TArg2> typename TBinFunc, typename T> 124 struct ListScanLeft; 125 126 template<typename TVal, template<typename TArg1, typename TArg2> typename TBinFunc, typename... TArgs> 127 struct ListScanLeft<TVal, TBinFunc, List<TArgs...>> 128 { 129 using Param = List<TArgs...>; 130 using Value = typename TBinFunc< 131 TVal, 132 typename Param::First 133 >::Result; 134 using Result = typename ListConnect< 135 List<Value>, 136 typename ListScanLeft< 137 Value, 138 TBinFunc, 139 typename Param::Rest 140 >::Result 141 >::Result; 142 }; 143 144 template<typename TVal, template<typename TArg1, typename TArg2> typename TBinFunc, typename TLast> 145 struct ListScanLeft<TVal, TBinFunc, List<TLast>> 146 { 147 using Param = List<TLast>; 148 using Value = typename TBinFunc< 149 TVal, 150 typename Param::First 151 >::Result; 152 using Result = List<Value>; 153 }; 154 155 template<typename T, T V, typename... TRest> 156 void PrintList(List<PODType<T, V>, TRest...>) 157 { 158 std::cout << V << ' '; 159 PrintList(List<TRest...>()); 160 } 161 162 template<typename T, T V> 163 void PrintList(List<PODType<T, V>>) 164 { 165 std::cout << V; 166 }
(果然只有静态高亮的C++代码看上去就和翔一样)
使用起来是这样的
1 List<Int<1>, Int<2>, Int<3>, Int<4>> list; 2 ListFoldLeft<Int<0>, Add, decltype(list)>::Result xxx; 3 ListScanLeft<Int<3>, Add, decltype(list)>::Result yyy; 4 PrintList(yyy);
foldl1,foldr,foldr1以及对应的scanr……啊啊啊啊啊啊啊啊啊
1 int main() 2 { 3 cout << L"我 整 个 人 都 递 归 了 ! ! ! ! ! ! 感 觉 自 己 充 满 了 力 量 ! ! ! ! ! !“; 4 main(); 5 }