这是昨天和今天写的东西,利用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<>, Int<>, Int<>, Int<>> list;
  2. ListFoldLeft<Int<>, Add, decltype(list)>::Result xxx;
  3. ListScanLeft<Int<>, Add, decltype(list)>::Result yyy;
  4. PrintList(yyy);

foldl1,foldr,foldr1以及对应的scanr……啊啊啊啊啊啊啊啊啊

  1. int main()
  2. {
  3. cout << L"我 整 个 人 都 递 归 了 ! ! ! ! ! ! 感 觉 自 己 充 满 了 力 量 ! ! ! ! ! !“;
  4. main();
  5. }

C++模板元编程 - 2 模仿haskell的列表以及相关操作的更多相关文章

  1. C++模板元编程 - 3 逻辑结构,递归,一点列表的零碎,一点SFINAE

    本来想把scanr,foldr什么的都写了的,一想太麻烦了,就算了,模板元编程差不多也该结束了,离开学还有10天,之前几天部门还要纳新什么的,写不了几天代码了,所以赶紧把这个结束掉,明天继续抄轮子叔的 ...

  2. 现代c++与模板元编程

    最近在重温<c++程序设计新思维>这本经典著作,感慨颇多.由于成书较早,书中很多元编程的例子使用c++98实现的.而如今c++20即将带着concept,Ranges等新特性一同到来,不得 ...

  3. C++模板元编程(C++ template metaprogramming)

    实验平台:Win7,VS2013 Community,GCC 4.8.3(在线版) 所谓元编程就是编写直接生成或操纵程序的程序,C++ 模板给 C++ 语言提供了元编程的能力,模板使 C++ 编程变得 ...

  4. C++模板元编程 - 函数重载决议选择工具(不知道起什么好名)完成

    这个还是基于之前实现的那个MultiState,为了实现三种类型“大类”的函数重载决议:所有整数.所有浮点数.字符串,分别将这三种“大类”的数据分配到对应的Converter上. 为此实现了一些方便的 ...

  5. C++模板元编程 - 挖新坑的时候探索到了模板元编程的新玩法

    C++真是一门自由的语言,虽然糖没有C#那么多,但是你想要怎么写,想要实现什么,想要用某种编程范式或者语言特性,它都会提供. 开大数运算类的新坑的时候(又是坑),无意中需要解决一个需求:大数类需要分别 ...

  6. 读书笔记_Effective_C++_条款四十八:了解模板元编程

    作为模板部分的结束节,本条款谈到了模板元编程,元编程本质上就是将运行期的代价转移到编译期,它利用template编译生成C++源码,举下面阶乘例子: template <int N> st ...

  7. c++ 模板元编程的一点体会

    趁着国庆长假快速翻了一遍传说中的.大名鼎鼎的 modern c++ design,钛合金狗眼顿时不保,已深深被其中各种模板奇技淫巧伤了身...论语言方面的深度,我看过的 c++ 书里大概只有 insi ...

  8. 一道模板元编程题源码解答(replace_type)

    今天有一同学在群上聊到一个比较好玩的题目(本人看书不多,后面才知是<C++模板元编程>第二章里面的一道习题), 我也抱着试一试的态度去完成它, 这道题也体现了c++模板元编程的基础和精髓: ...

  9. effective c++ Item 48 了解模板元编程

    1. TMP是什么? 模板元编程(template metaprogramming TMP)是实现基于模板的C++程序的过程,它能够在编译期执行.你可以想一想:一个模板元程序是用C++实现的并且可以在 ...

随机推荐

  1. Linux定时任务Crontab执行PHP脚本

    http://blog.chinaunix.net/uid-7552018-id-182133.html crontab执行php脚本 http://www.jb51.net/article/2913 ...

  2. compiler

    http://www.lingcc.com/2012/05/16/12048/ a list of compiler books — 汗牛充栋的编译器参考资料 Posted on 2012年5月16日 ...

  3. 一次zabbix的渗透

    wget http://xxxxxxx:8888/back.py -O  /tmp/1.py  写入python反弹马 反弹到vps python /tmp/back.py IP port       ...

  4. X-UA-Compatible设置兼容模式

    原文地址:http://www.cnblogs.com/kingboy2008/archive/2011/07/01/2226424.html   IE浏览器的兼容性一直是网站开发人员头疼的事情,众所 ...

  5. linq 和 , 并 , 差 ,交

        假如: A = [--.], B = [-.] A 并 B = 全部     linq : a.union(b)   A 交 B = 中间那块    linq: a.Intersect(b) ...

  6. Android 常遇错误解决方案

    遇到问题描述: 运行android程序控制台输出 [2012-07-18 16:18:26 - ] The connection to adb is down, and a severe error ...

  7. python中保留两位小数

    今天写程序的时候碰到了一个问题关于如何控制浮点数只显示小数点后两位,正常的想法是用round函数,例如 round(a, 2),但是在面对下面的问题时候round就不太好用了 >>> ...

  8. 解决Centos6.5虚拟机上网问题

    起初是为了能通过上网的方式简化g++的安装,故有此篇博文,希望能帮助到有需要的人. 虚拟机环境: 1.Linux系统:Centos6.5 64位 2.ifconfig查看虚拟机ip:竟然没有ip! 3 ...

  9. PHP使用1个crontab管理多个crontab任务

    http://www.binarytides.com/php-manage-multiple-cronjobs-with-a-single-crontab-entry/ In many php app ...

  10. 从一次异常中浅谈Hibernate的flush机制

    摘自http://www.niwozhi.net/demo_c70_i1482.html http://blog.itpub.net/1586/viewspace-829613/ 这是在一次事务提交时 ...