一、lamba表达式如何捕获外部变量
#include <iostream>
using namespace std;
void main()
{
int num1 = 100;
int num2 = 99;
[=]() {cout << num1 << num2 << endl; }(); //=只能读不能写
// [=]() {num1 = 22, cout << num1 << num2 << endl; }();// C3491 “num1” : 无法在非可变 lambda 中修改通过复制捕获
cin.get();
}
总结:[=]可以捕获外部变量,但是只能读不能写
#include <iostream>
using namespace std;
void main()
{
int num1 = 100;
int num2 = 99;
[=]()mutable {num1 = 666; cout << num1 << num2 << endl; }(); //666999mutable改变副本
cout << num1 << num2 << endl; //10099
cin.get();
}
总结:mutable可以改变外部变量的副本
#include <iostream>
using namespace std;
void main()
{
int num1 = 100;
int num2 = 99;
[&]() {num1 = 11, cout << num1 << num2 << endl; }(); //1199 &表示读写外部变量,改变原本
cout << num1 << num2 << endl; //1199
cin.get();
}
总结:[&]可以捕获并读写外部变量的原本
#include <iostream>
using namespace std;
void main()
{
int num1 = 100;
int num2 = 99;
[=]() {cout << &num1 << ","<< num2 << endl; }(); //=只能读不能写
cout << &num1 << "," << num2 << endl;
//两个地址不同,说明是不同的内存,=的操作是复制原本给lamba表达式,
[&]() {cout << &num1 << "," << num2 << endl; }(); //=只能读不能写
cout << &num1 << "," << num2 << endl;
//&地址相同,表示以引用的方式捕获外部变量,操作同一块内存,因此可以改写原本
[=]()mutable {num1 = 666; cout <<& num1 << "," << num2 << endl; }();
//mutalbe是一个声明,表示操作副本,可以看作是=的补充
cin.get();
}
总结:
- &表示以引用的方式捕获外部变量,因此可以直接对外部变量内存进行读写
- =表示以值传递的方式捕获外部变量,因此不能改变外部变量,matable是对=的补充
- 必须显示的捕获,没有隐式的捕获
二、单独改变捕获某一个值
#include <iostream>
using namespace std;
void main()
{
int a = 10;
int b = 9;
int c = 15;
//[&a]() {a = 100; cout << a << b << c << endl; }(); //无法隐式捕获“b/c”,因为尚未指定默认捕获模式, 封闭函数局部变量不能在 lambda 体中引用,除非其位于捕获列表中
[&a, b, c]() {a = 100; cout << a << b << c << endl; }(); //b可以改变a的原本
cout << a << endl; //1000
cin.get();
}
#include <iostream>
using namespace std;
void main()
{
int a = 10;
int b = 9;
int c = 15;
[a, b, c]()mutable {a = 999; b = 333; cout << a << " "<< b << " " << c; }(); //999 333 15
cout <<"\n"<< a << " " << b << endl; //10 9
//[]()mutable {a = 999; b = 333; cout << a << " " << b << " " << c; }(); //封闭函数局部变量不能在 lambda 体中引用,除非其位于捕获列表中 Cpp.cpp e : \C++\Cpp.cpp\Cpp.cpp\类型转换.cpp 15
cin.get();
}
总结:mutable捕获外部变量,改变副本
三、auto自动推理数据类型
#include <iostream>
using namespace std;
void main()
{
[](auto a, auto b){cout << a + b << endl; }(10, 11); //auto可以推理数据类型
[](auto a, auto b){cout << a + b << endl; }(10.8, 11);
[](auto a = 0 , auto b = 0 ){cout << a + b << endl; }(10, 11);
cin.get();
}
四、lamba表达式与数组
#include <iostream>
#include <array>
#include <algorithm>
using namespace std;
void main()
{
array<int, 10>myint{ 1, 2, 3, 4, 5, 6, 7 };
for_each(myint.begin(), myint.end(), [](int num) {cout << num << " "; }); //显示 1, 2, 3, 4, 5, 6, 7 0 0 0
cout << "\n";
for_each(myint.begin(), myint.end(), [](int num) {num += 1, cout << num << " "; }); //修改副本,函数传参副本机制,因此修改的是副本
cout << "\n";
for_each(myint.begin(), myint.end(), [](int num) {cout << num << " "; }); //显示 1, 2, 3, 4, 5, 6, 7 0 0 0
cout << "\n *******************\n" ;
for_each(myint.begin(), myint.end(), [](int &num) {num += 1, cout << num << " "; }); //修改原本,引用原本,对原本进行操作,因此会修改原本
cout << "\n";
for_each(myint.begin(), myint.end(), [](int num) {cout << num << " "; }); //显示,2,3,4,5,6,7,8,1,1,1
cin.get();
}
总结:
- 函数传参如果是值传递,那么副本机制修改副本;如果是引用传参,那么操作原本
- lamba表达式是为了解决代码内嵌问题
- [](){}()匿名lamba表达式
- for_each常常用来遍历容器,比如数组
- array<int, n>{0};是CPP风格的数组
- lamba表达式中[=]表示值捕获外部遍历,[&]表示引用捕获。