8lambda高级

一、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表达式中[=]表示值捕获外部遍历,[&]表示引用捕获。

猜你喜欢

转载自blog.csdn.net/zhizhengguan/article/details/80992360