免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 11182 | 回复: 26

一个匿名的lambda函数如何递归的调用自己? [复制链接]

论坛徽章:
0
发表于 2012-05-28 15:29 |显示全部楼层
10可用积分
普通函数是有名字的,递归调用没有问题。

那么lambda函数如何能递归的调用自身呢? 谢谢!

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
发表于 2012-05-28 18:28 |显示全部楼层
普通的做法:函数表达式而非匿名函数。
既然是表达式,也就可以随处写,而不像函数语句那样必须写在特定位置。
同时既然不是匿名,就可以命名。

js与clojure就是这样的

  1. (function f(x) { return x>1? x*f(x-1): 1 })(12) // JS
  2. ((fn f [x] (if (> x 1) (* x (f (- x 1))) 1)) 12) ; Clojure
复制代码
但C++11的lambda是匿名函数,不能这么玩……


文艺的做法:不动点组合子
在C++11里需要处理:
1) 生命周期 —— 如果不使用gc
2) 类型 —— 包括不同类型签名,以及f(f)的类型。

看这个: http://codereview.stackexchange. ... d-under-vistual-stu

论坛徽章:
0
发表于 2012-05-28 18:29 |显示全部楼层
要用function
  1. #include <functional>
  2. #include <stdio.h>

  3. int main()
  4. {
  5.     std::function<int(int)> fib = [&fib](int n) -> int
  6.     {
  7.         return (n<=2) ? (1) : (fib(n-1)+fib(n-2));
  8.     };

  9.     printf("%d\n", fib(10));
  10.     return 0;
  11. }
复制代码

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
发表于 2012-05-28 18:51 |显示全部楼层
补充一下,JS与Clojure的named function expression的name的作用域是在被调用函数(callee)中当中而非调用者(caller)中。
ecmascript5:

  1. // caller scope
  2. [1,2,3].map(function f(x) { /*callee scope*/return x>1? x*f(x-1): 1 }) // [1,2,6]
  3. // caller scope
复制代码
Clojure同理:

  1. // caller scope
  2. (map (fn f [x] "callee scope" (if (> x 1) (* x (f (- x 1))) 1)) '(1 2 3)) ; (1 2 6)
  3. // caller scope
复制代码
前面提到的:http://codereview.stackexchange. ... d-under-vistual-stu
可以达到这样的效果:

  1. // caller scope
  2. transform(beg, end, dst,
  3. getFix([](std::function<int (int)> f) -> std::function<int (int)>{
  4. // callee scope
  5.         return [f](int n)->int { if(n==0) return 1; else return n * f(n-1); };
  6. }) );
  7. // caller scope
复制代码
注意getFix的参数, 不是阶乘本身, 而是一个返回函数的函数。 返回的函数中才包含了阶乘计算。通过这样绕过生命周期问题。
再通过loopfunc_t绕过f(f)的类型问题。
最后用变长模板参数解决签名问题。

PS: 实践中最好不要这样玩,这已经超出C++的能力了。
实践中,让函数名在caller scope但又不是top-level的机制在C++98就存在了, 就是inner class。

论坛徽章:
0
发表于 2012-05-28 19:38 |显示全部楼层
你们在说什么?是希望有这样的语法吗?
我怀疑现有的语法结构下,已经很难和谐的加进去一些东西。

  1. int main()
  2. {
  3.      print( [&]fib(int n) -> int
  4.          {
  5.              return (n<=2) ? (1) : (fib(n-1)+fib(n-2));
  6.          });

  7. }
复制代码

论坛徽章:
0
发表于 2012-05-28 19:57 |显示全部楼层
                  

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
发表于 2012-05-28 20:20 |显示全部楼层
回复 5# AD8018

这也行?还是只是你想象中的语法?

论坛徽章:
0
发表于 2012-05-29 04:34 |显示全部楼层
回复 7# OwnWaterloo


你是不是退化到连中文都看不懂了?

论坛徽章:
0
发表于 2012-05-29 09:45 |显示全部楼层
OwnWaterloo 发表于 2012-05-28 20:20
回复 5# AD8018

这也行?还是只是你想象中的语法?


纯属臆想

论坛徽章:
0
发表于 2012-05-29 16:59 |显示全部楼层
本版折腾 C++11 的来齐了?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

SACC2019中国系统架构师大会

【数字转型 架构演进】SACC2019中国系统架构师大会
2019年10月31日~11月2日第11届中国系统架构师大会(SACC2019)将在北京隆重召开。四大主线并行的演讲模式,1个主会场、20个技术专场、超千人参与的会议规模,100+来自互联网、金融、制造业、电商等领域的嘉宾阵容,将为广大参会者提供一场最具价值的技术交流盛会。




----------------------------------------

大会官网>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP