zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    css word-wrap与word-break区别
    input输入框光标位置问题
    正则表达式(二)- 位置匹配攻略
    正则表达式(一)- 字符匹配攻略
    mac电脑重启nginx报错nginx: [error] invalid PID number "" in "/usr/local/var/run/nginx.pid"
    指定js文件不使用 eslint 语法检查
    管理github/gitlab生成多个ssh key
    前端切图两种方法整理
    梳理:移动端Viewport的知识
    切图 — Photoshop(转载)
  • 原文地址:https://www.cnblogs.com/pointer-smq/p/4779462.html
Copyright © 2011-2022 走看看