C/C++C/C++C++ lamda表达式
foresta.yang创建一个匿名函数并执行。Objective-C采用的是上尖号^,而C++ 11采用的是配对的方括号[]。实例如下:
1 2 3 4 5 6 7 8
| #include <iostream> using namespace std; int main() { []{ cout << "Hello,Worldn"; }(); }
|
我们也可以方便的将这个创建的匿名函数赋值出来调用:
1 2 3 4 5 6 7 8 9 10
| #include <iostream> using namespace std; int main() { int i = 1024; auto func = [](int i) { cout << i; }; func(i); }
|
捕获选项
- [] Capture nothing (or, a scorched earth strategy?)
- [&] Capture any referenced variable by reference
- [=] Capture any referenced variable by making a copy
- [=, &foo] Capture any referenced variable by making a copy, but capture variable foo by reference
- [bar] Capture bar by making a copy; don’t copy anything else
- [this] Capture the this pointer of the enclosing class
1 2 3 4 5 6 7 8 9 10 11
| -[]不捕获任何变量
-[&]通过引用捕获任何引用变量
-[=]通过复制捕获任何引用变量
-[=,&foo]通过复制捕获任何引用的变量,但通过引用捕获变量foo
-[bar]通过复制来捕获bar;不要复制其他任何东西
-[this]捕获封闭类的this指针
|
[] 不捕获任何变量
1 2 3 4 5 6 7 8
| #include <iostream> using namespace std; int main() { int i = 1024; auto func = [] { cout << i; }; func(); }
|
vs 报错
error C3493: 无法隐式捕获“i”,因为尚未指定默认捕获模式
error C2064: 项不会计算为接受 0 个参数的函数
g++ 报错:
error: ‘i’ is not captured
要直接沿用外部的变量需要在 [] 中指名捕获。
[=] 拷贝捕获
1 2 3 4 5 6 7 8 9 10
| #include <iostream> using namespace std; int main() { int i = 1024; auto func = [=]{ cout << i; }; func(); }
|
结果:
1024
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #include <iostream> using namespace std; int main() { int i = 1024; auto fun1 = [=]{ cout << i; auto fun2 = []{ cout << i; }; fun2(); }; fun1(); }
|
[&] 引用捕获
1 2 3 4 5 6 7 8 9 10 11
| #include <iostream> using namespace std; int main() { int i = 1024; cout << &i << endl; auto fun1 = [&]{ cout << &i << endl; }; fun1(); }
|
结果:
0x28ff0c
0x28ff0c
[=, &] 拷贝与引用混合
1 2 3 4 5 6 7 8 9 10 11 12 13
| #include <iostream> using namespace std; int main() { int i = 1024, j = 2048; cout << "i:" << &i << endl; cout << "j:" << &j << endl; auto fun1 = [=, &i]{ cout << "i:" << &i << endl; cout << "j:" << &j << endl; }; fun1(); }
|
结果
outside i:0x28ff0c
outside j:0x28ff08
inside i:0x28ff0c
inside j:0x28ff04
[bar] 指定引用或拷贝
1 2 3 4 5 6 7 8 9 10 11 12
| #include <iostream> using namespace std; int main() { int i = 1024, j = 2048; cout << "outside i value:" << i << " addr:" << &i << endl; auto fun1 = [i]{ cout << "inside i value:" << i << " addr:" << &i << endl; }; fun1(); }
|
结果:
outside i value:1024 addr:0x28ff08
inside i value:1024 addr:0x28ff04
1 2 3 4 5 6 7 8 9 10 11 12
| #include <iostream> using namespace std; int main() { int i = 1024, j = 2048; cout << "outside i value:" << i << " addr:" << &i << endl; auto fun1 = [&i]{ cout << "inside i value:" << i << " addr:" << &i << endl; }; fun1(); }
|
结果:
outside i value:1024 addr:0x28ff08
inside i value:1024 addr:0x28ff08
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <iostream> using namespace std; int main() { int i = 1024, j = 2048, k; cout << "outside i:" << &i << endl; cout << "outside j:" << &j << endl; auto fun1 = [i, &j]{ cout << "inside i:" << &i << endl; cout << "inside j:" << &j << endl; }; fun1(); }
|
结果:
outside i:0x28ff0c
outside j:0x28ff08
inside i:0x28ff00
inside j:0x28ff08
[this] 捕获 this 指针
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| #include <iostream> using namespace std; class test { public: void hello() { cout << "test hello!n"; }; void lambda() { auto fun = [this]{ this->hello(); }; fun(); } };
int main() { test t; t.lambda(); }
|