c++实现类似Common Lisp的多参数加法和比较

在CL里我们可以这样:

1 $ sbcl

2 * (+ 1 2 3)

3 6

4 * (< 1 2 3)

5 T

6 * (< 2 3 1)

7 NIL

8 * 

从简单的方面看, CL的+和<就是一个接收多参数的函数,有点类似cpp的add(1,2,3)和less(1,2,3)这样.

所以当C++11开始有了变参模板以后, 就可以玩多参数的加法和多参数比较了

 1 #include <functional>

 2 template<typename O, typename A,typename B>

 3 bool cmp(O o, A a,B b){

 4     return o(a, b);

 5 }

 6 template<typename O, typename A,typename B,typename... C>

 7 bool cmp(O o,A a,B b,C... c){

 8     return o(a, b) and cmp(o,b,c...);

 9 }

10 template<typename O, typename A,typename B>

11 A reduce(O o, A a,B b){

12     return o(a, b);

13 }

14 template<typename O, typename A,typename B,typename... C>

15 A reduce(O o,A a,B b,C... c){

16     return reduce(o,o(a, b),c...);

17 }

18 

19 bool foo(int a,int b,int c,int d){

20   return cmp(std::less<int>(), a,b,c,d);

21 }

22 int bar(int a,int b,int c,int d){

23   return reduce(std::plus<int>(), a,b,c,d);

24 }

可能有人会说,这不是坑爹么, 先不管写法比CL的丑, 你还递归调用了,简直弱爆了.....

让我们来看看真相(clang):

 1 foo(int, int, int, int):                             # @foo(int, int, int, int)

 2     cmpl    %esi, %edi

 3     jge    .LBB0_1

 4     cmpl    %edx, %esi

 5     setl    %sil

 6     cmpl    %ecx, %edx

 7     setl    %al

 8     andb    %sil, %al

 9     ret

10 .LBB0_1:

11     xorl    %eax, %eax

12     ret

13 

14 bar(int, int, int, int):                             # @bar(int, int, int, int)

15     addl    %esi, %edi

16     leal    (%rdi,%rdx), %eax

17     addl    %ecx, %eax

18     ret

和手写的完全没差噢, 稍微是丑一点,不过你看下CL的汇编, 肯定比C++的慢....(逃

最后,这有啥用?

多参数加法似乎是没啥用处了,还不如写a+b+c+d呢
多参数比较还行

a < b and b < c and c < d

你可能感兴趣的:(common lisp)