C++模板元编程

这是昨天和今天写的东西,利用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 }
原文地址:https://www.cnblogs.com/pointer-smq/p/4779462.html