免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: donet8
打印 上一主题 下一主题

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

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
21 [报告]
发表于 2014-03-23 21:11 |只看该作者
回复 19# OwnWaterloo

额……lambda的定义不就是“匿名函数”么?有名字就不是lambda了…………

话说回来,莫非你不能这么写么?

  1. std::function<void()> f=[&f](){ f(); };
复制代码

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
22 [报告]
发表于 2014-03-23 22:29 |只看该作者
回复 20# windoze

正式因为这个。。。 所以JS换了一个术语,叫函数表达式(function expression),而不叫匿名函数。因为可以可选地为它命个名。
而Clojure里的匿名函数字面量值的是这个: Macro characters
Anonymous function literal (#())
#(...) => (fn [args] (...))

fn本身是可以命名的。


  1. std::function<void()> f=[&f](){ f(); };
复制代码
的区别是作用域不同。 f的作用域在body之外, 而JS和Clojure可以在body内部。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
23 [报告]
发表于 2014-03-23 23:13 |只看该作者
OwnWaterloo 发表于 2014-03-23 22:29
回复 20# windoze

正式因为这个。。。 所以JS换了一个术语,叫函数表达式(function expression),而不叫匿名函数。因为可以可选地为它命个名。
而Clojure里的匿名函数字面量值的是这个: Macro characters

    Anonymous function literal (#())
    #(...) => (fn [args] (...))


fn本身是可以命名的。



    std::function<void()> f=[&f](){ f(); };

复制代码
的区别是作用域不同。 f的作用域在body之外, 而JS和Clojure可以在body内部。


std::function<void()> f = [&f](){f();};
这是是将一个 lambda 转换到了 std::function<void()>,调用了 
function<void()> 的 constructor;

在 libstdc++ 之前的 std::function 的实现中,这个 std::function<void()> 的效率有损失;当前的代码有优化,但是也引入了另外的 bug,可能会产生内存泄露,目前还木有人报告过。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
24 [报告]
发表于 2014-03-23 23:15 |只看该作者
OwnWaterloo 发表于 2014-03-23 18:45
回复 14# lost_templar

用...塞进去不正是因为C++11的lambda是匿名的么?

对比前面Javascript和Clojure的例子,函数表达式可以有一个可选的名字,然后在函数的body里可以引用自己。没有将递归用的函数作为参数传入。


我理解的匿名是这个 lambda 函数的类型是不可知的;你的意思难道是指这个函数名称是不可知的?

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
25 [报告]
发表于 2014-03-23 23:26 |只看该作者
回复 23# lost_templar

我感觉LZ指的就是lambda本身匿名 —— 所以才会提到如何递归 —— 而不是lambda的类型。。。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
26 [报告]
发表于 2014-03-23 23:49 |只看该作者
回复 24# OwnWaterloo


    我理解为类型不可知是因为这个例子:
  1. cat ld.cc && g++-4.9 -o ld ld.cc -std=c++11 && ./ld
  2. #include <iostream>

  3. struct enen
  4. {
  5.     template< typename T>
  6.     void operator()(T, T) const
  7.     {
  8.         std::cout << "same type.\n";
  9.     }
  10.     template< typename T, typename U >
  11.     void operator()(T, U) const
  12.     {
  13.         std::cout << "different types.\n";
  14.     }
  15. };


  16. int main()
  17. {
  18.     enen()( [](){ return 0; }, [](){ return 0; } );

  19.     return 0;
  20. }

  21. different types.
复制代码
即使是同样的 lambda 函数,也会被判断微不同的类型,很囧的

论坛徽章:
44
15-16赛季CBA联赛之浙江
日期:2021-10-11 02:03:59程序设计版块每日发帖之星
日期:2016-07-02 06:20:0015-16赛季CBA联赛之新疆
日期:2016-04-25 10:55:452016科比退役纪念章
日期:2016-04-23 00:51:2315-16赛季CBA联赛之山东
日期:2016-04-17 12:00:2815-16赛季CBA联赛之福建
日期:2016-04-12 15:21:2915-16赛季CBA联赛之辽宁
日期:2016-03-24 21:38:2715-16赛季CBA联赛之福建
日期:2016-03-18 12:13:4015-16赛季CBA联赛之佛山
日期:2016-02-05 00:55:2015-16赛季CBA联赛之佛山
日期:2016-02-04 21:11:3615-16赛季CBA联赛之天津
日期:2016-11-02 00:33:1215-16赛季CBA联赛之浙江
日期:2017-01-13 01:31:49
27 [报告]
发表于 2014-03-24 00:20 |只看该作者
回复 25# lost_templar

  1. int a;
  2. auto l=[&a](){ ... };
复制代码
语法上相当于:

  1. int a;
  2. struct {
  3.    int &a;
  4.    void operator()(){ ... }
  5. } l({a});
复制代码
每次的匿名struct都是临时定义的,所以每个lambda都有唯一的类型,和其它所有lambda都不同。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP