- 论坛徽章:
- 2
|
本帖最后由 OwnWaterloo 于 2015-11-19 22:13 编辑
回复 13# fender0107401
这个是匿名函数。
- #include <assert.h>
- int main(int argc, char* argv[])
- {
- auto add = [](int a, int b) { return a+b; };
- assert(add(1,2)==3);
- }
复制代码 有参数列表后会不会熟悉点了。。。
如果不需要参数就可以省略括号
- #include <stdio.h>
- #include <stdlib.h>
- int main(int argc, char* argv[])
- {
- atexit([](void){ printf("(void)\n"); });
- atexit([]( ){ printf("()\n"); });
- atexit([] { printf("omitted\n"); });
- }
复制代码 []{}就是一个接受0个参数并且不做任何事的函数。。。
因为函数可以随处写了,于是就有一个写在顶层的函数不具备的功能。 []和那个功能有关。。。
写在顶层的函数,除了参数之外, 只要有相应的声明还可以访问其他的函数或变量。 这些函数或变量的生命周期都差不多是整个程序执行期间。
而匿名函数除了参数和静态生命周期的函数变量之外, 可以访问一些其他函数的局部变量。
比如前面的argc和argv, 还有add也是main的局部变量。
既然是局部变量, 它的生命周期就会更短。 并且c++也没有垃圾回收, 于是对局部变量的访问就保守一点。。。
[]中就是用来显式地控制函数体{}中可以访问哪些非参数中的变量, 以及以什么形式访问。。。。
[]不允许访问任何非参数非静态生命周期的东西。 除此之外最简单的形式就是[=]和[&]:- #include <assert.h>
- #include <stdio.h>
- int main(int argc, char* argv[])
- {
- int v = 0;
- auto byval = [=]/* () -> const int* */{ return &v; };
- assert(byval() != &v);
- int v1 = *byval(); assert(v1==0);
- v = 1;
- int v2 = *byval(); assert(v2==0);
- int r = 0;
- auto byref = [&]/* () -> int* */{ return &r; };
- assert(byref() == &r);
- int r1 = *byref(); assert(r1==0);
- r = 1;
- int r2 = *byref(); assert(r2==1);
- }
复制代码 byval 以[=]的形式访问(捕获)了不是参数也不是静态变量,而是main的局部变量的v。 [=]允许随意访问。。。 要访问argc,argv也是可以的。
byval创建之后, 它里面的v是外面的v的复制([=]中等号=借用了赋值的含义)。
byref 以[&]的形式捕获了r。 两者是同一个整数变量。 ([&]中的&借用了取地址的含义)。
注释里面是返回类型的写法, 在编译器可以推导出来时可以省略。
总之, 这和其他语言里面的匿名函数以及写在顶层的函数没有太大的区别。。。 参数列表,函数体,返回类型(位置稍微有点变动)。。。
区别最大的应该就是[]了。
其他大部分语言都有垃圾回收, 所以不太需要这个东西。
c++没有, 于是就把管理生命周期的责任再次推给程序员了 |
|