這是昨天和今天寫的東西,利用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彷佛只能使用函數來輸出了。spa
寫着寫着也發現本身的模板元編程的編碼和命名風格在不斷完善,果真要不停寫才能體會到東西。設計
(話說默認字體大小怎麼改啊,13px纔好看嘛)code
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++代碼看上去就和翔同樣)blog
使用起來是這樣的繼承
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……啊啊啊啊啊啊啊啊啊ast
1 int main() 2 { 3 cout << L"我 整 個 人 都 遞 歸 了 ! ! ! ! ! ! 感 覺 自 己 充 滿 了 力 量 ! ! ! ! ! !「; 4 main(); 5 }