c++实现类似Common Lisp的多参数加法和比较
在CL里我们可以这样:
$ sbcl
* (+ 1 2 3)
6
* (< 1 2 3)
T
* (< 2 3 1)
NIL
*
从简单的方面看, CL的+和<就是一个接收多参数的函数,有点类似cpp的add(1,2,3)和less(1,2,3)这样.
所以当C++11开始有了变参模板以后, 就可以玩多参数的加法和多参数比较了
#include <functional>
template<typename O, typename A,typename B>
bool cmp(O o, A a,B b){
return o(a, b);
}
template<typename O, typename A,typename B,typename... C>
bool cmp(O o,A a,B b,C... c){
return o(a, b) and cmp(o,b,c...);
}
template<typename O, typename A,typename B>
A reduce(O o, A a,B b){
return o(a, b);
}
template<typename O, typename A,typename B,typename... C>
A reduce(O o,A a,B b,C... c){
return reduce(o,o(a, b),c...);
} bool foo(int a,int b,int c,int d){
return cmp(std::less<int>(), a,b,c,d);
}
int bar(int a,int b,int c,int d){
return reduce(std::plus<int>(), a,b,c,d);
}
可能有人会说,这不是坑爹么, 先不管写法比CL的丑, 你还递归调用了,简直弱爆了.....
让我们来看看真相(clang):
foo(int, int, int, int): # @foo(int, int, int, int)
cmpl %esi, %edi
jge .LBB0_1
cmpl %edx, %esi
setl %sil
cmpl %ecx, %edx
setl %al
andb %sil, %al
ret
.LBB0_1:
xorl %eax, %eax
ret bar(int, int, int, int): # @bar(int, int, int, int)
addl %esi, %edi
leal (%rdi,%rdx), %eax
addl %ecx, %eax
ret
和手写的完全没差噢, 稍微是丑一点,不过你看下CL的汇编, 肯定比C++的慢....(逃
最后,这有啥用?
多参数加法似乎是没啥用处了,还不如写a+b+c+d呢
多参数比较还行
a < b and b < c and c < d
c++实现类似Common Lisp的多参数加法和比较的更多相关文章
- ANSI Common Lisp Practice - My Answers - Chatper - 3
Ok, Go ahead. 1 (a) (b) (c) (d) 2 注:union 在 Common Lisp 中的作用就是求两个集合的并集.但是这有一个前提,即给的两个列表已经满足集合的属性了.具体 ...
- Common Lisp编译程序的小技巧
这几天开始玩Common Lisp,遇上了一个有意思的问题,CL一般是解释运行,也有实现可以编译生成字节码(fas文件).我正在用的两种CL实现是SBCL和CLISP,前者是我从<实用Commo ...
- Common Lisp第三方库介绍 | (R "think-of-lisper" 'Albertlee)
Common Lisp第三方库介绍 | (R "think-of-lisper" 'Albertlee) Common Lisp第三方库介绍 一个丰富且高质量的开发库集合,对于实际 ...
- common lisp和scheme的区别
1. 在Common Lisp 眼中,一个符号的symbol-value 和symbol-function 是不一样的,而Scheme对两者不作区分.在Scheme 里面,变量只有唯一对应的值,它可以 ...
- Common Lisp中的读取宏 ' #' `( , ,@) #( ) #na( ) #<OBJECT> :Keyword
当你把 xx 当做符号使用时 'xx , 这个符号是没有任何函数/变量语义的, 仅仅是一个 符号而已(就像一个string一样) 但你可以对这个string有其他的用法,比如使用它所bind ...
- 搭建fedora开发环境 common lisp, c++, go
第三方软件库: http://download1.rpmfusion.org/free/fedora/releases/25/Everything/x86_64/os/repoview/index.h ...
- Difference between LET and LET* in Common LISP
Difference between LET and LET* in Common LISP LET Parallel binding which means the bindings com ...
- scheme和common lisp 区别
Scheme and Common Lisp use different names for some of the basic system functions. Many Lisp program ...
- slime+sbcl for common lisp
sudo apt-get install slime audo apt-get install sbcl ;;sbcl+slime for common lisp ;;sudo apt-get ins ...
随机推荐
- Oracle 中 union与union all
如果我们需要将两个select语句的结果作为一个整体显示出来,我们就需要用到union或者union all关键字. union(或称为联合)的作用是将多个结果合并在一起显示出来. union和uni ...
- ECshop模板机制
ECshop模板机制整理 模板机制 近期新项目涉及到ECshop的二次开发,趁此良机正好可以对闻名已久的ECshop系统进行深入了解.要了解一个系统,那么该系统的模板机制就是最重要的一环.相关整理如下 ...
- MySQL索引使用方法和性能优化
在自己的一个项目中,数据比较多,搜索也很频繁,这里找到一个建立索引很不错的文章,推荐下. 关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的 ...
- 中国大概能用的NTPserver地址
133.100.11.8 prefer210.72.145.44203.117.180.36131.107.1.10time.asia.apple.com64.236.96.53130.149.17. ...
- 产生不重复的随机数TGUID
uses ActiveX; procedure TForm1.BtnNewClick(Sender: TObject);var ID: TGUID; S: string;begin if CoC ...
- [Bootstrap] 7. Working Herader
<header class="navbar navbar-default navbar-static-top"> <div class="contain ...
- java推断字符串是否为乱码
项目中有一个功能 在IE中GET方式提交会产生乱码 但有两个入口都会走这同一段代码 固不能直接转码,所以要进行推断传过来的该值是不是乱码 可用下面方式验证: java.nio.charset.Char ...
- 在centos上使用yum安装redis及php扩展php-redis
.wget http://mirrors.ustc.edu.cn/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm rpm -ivh epel-rele ...
- c++ primer,友元函数上的一个例子(By Sybase)
本文试图解释c++ primer Screen 和 Window_Mgr的例子,为什么将两个类放在两个文件中无法编译? 将两个类写在同一个文件中,通过三个例子解释问题: 第一种写法问题: 编译到Scr ...
- js之parentElement属性
<html> <head> </head> <body> <form name="a "> <table name ...