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 ...
随机推荐
- MySQL 常用语句 (汇集)
原文地址:MySql常用语句作者:wuyanle 一.mysql常用语句 创建,删除和最基本查询: 显示数据库 mysql->show databases; 创建数据库 mysql-> ...
- IDF实验室-python ByteCode writeup
题目地址:http://ctf.idf.cn/index.php?g=game&m=article&a=index&id=45 下载来发现是crackme.pyc 可以用unc ...
- zxing 生成二维码
一.zxing介绍 zxing是google提供生成.解析一维码.二维码的开源库. 二.使用 2.1 maven pom 配置 <dependency> <groupId>co ...
- mysql select 报错
代码片段: sql_url = "select * from webpage where url = '%s'" % b try: cursor.execute(sql_url) ...
- mac os升级为 Yosemite 10.10 后不能创建javaproject
出现这样的情况可能是因为mac系统升级导致JAVA的安装路径发生改变(Xcode升级后也出现模拟器位置改变的情况,不要奇怪) 之前安装的eclipse就自然找不到SDK的路径了,所以会捆绑失败 接下来 ...
- W5500问题集锦(二)
attachment_id=5620" rel="attachment wp-att-5620" style="margin:0px; padding:0px; ...
- android图片处理方法(不断收集中)
//压缩图片大小 public static Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArr ...
- CentOS命令行无线上网
(1)首先关闭开发板的有线网卡[root@FriendlyARM /]# ifconfig eth0 down(2)加载USB WiFi无线网卡[root@FriendlyARM /]# ifconf ...
- iOS使用宏写单例
本文只介绍ARC情况下的单例 过去一直背不下来单例如何写,就是知道这么回事,也知道通过宏来写单例,但是一直记不住,今天就来记录一下 - (void)viewDidLoad { [super v ...
- android学习日记26--AIDL之进程间的通信
1.AIDL介绍 AIDL:Android Interface Definition Language,即Android接口定义语言. 由于每个应用程序都运行在自己的进程空间,并且可以从应用程序UI运 ...