lambda相当于一个匿名函数一样使用
但是它并非是匿名函数,编译器会为我们生成一个类,lambda的类,如果用auto接实际上返回的是一个函数对象
我们今天详细讲一下lambda的捕获
#include<iostream>
class Demo {
public:
Demo(int i):m(i){}
void operator()() {
[this] {std::cout << m << std::endl; }();
}
void demo(int a) {
[=,this] { this->m = a; }();//有所不同的是只需要this就可以修改成员变量的值了
}
void test() {
[this] {this->m = 111; }(); //其实加不jia=都可以直接改变成员变量,但是没用=捕获的话没办法获取传入的值,不能像上面那样
}
private:
int m = 0;
};
int main() {
//当不接收参数的时候可以省略(),最后加上()是为了调用,下面这些产生的结果是一样的,至少在目前是的
std::cout << [] { return 5; }() << std::endl;
std::cout << []()->decltype(auto) {return 5; }() << std::endl;
std::cout << []()->int {return 5; }() << std::endl;
std::cout << []()->auto {return 5; }() << std::endl;
int a = 0;
//或者接收参数
auto p = [](int b) {std::cout << b << std::endl; };
p(a);
auto p2 = [](auto b) {std::cout << b << std::endl; };
p2(a);
//或者直接捕获 下面的区别无非是捕获整个作用域和捕获具体的变量
[=] {std::cout << a << std::endl; }();
[i = a] {std::cout << i << std::endl; }();
//或者直接修改
[&] {a = 100; std::cout << a << std::endl; }();
[&a] {a = 100; std::cout << a << std::endl; }();
[ca=std::as_const(a)] ()mutable {ca = 10; std::cout << ca << std::endl; }();
std::cout << a << std::endl;
//下面这是在类内的捕获情况
Demo demo(10);
demo();
demo.demo(123);
demo();
demo.test();//这种方式是无法改变成员变量的值的
demo();
//其实还有很多操作,最后补充一下,可以像下面这样
int e(0), f(0), g(0);
[E = e, F = f, G = g] {std::cout << E << ' ' << F << ' ' << G << std::endl; }();
[&E = e, &F = f, &G = g] {E = 1, F = 2, G = 3; std::cout << E << ' ' << F << ' ' << G << std::endl; }();
std::cout << e << ' ' << f << ' ' << g << std::endl;
//另外,不省略()然后->指定类型啥的其实都行,如果是引用捕获的时候()mutable的话也合法,虽然没啥区别,先这样,语法糖而已
return 0;
}
我们顺便再提一下C++14提出的可以在lambda内使用auto简单的说就是能给lambda的形参类型写成auto
演示如下
#include<iostream>
#include<string>
#include<array>
#include<algorithms>
/*在C++14 中引入的泛型lambdas,是一种成员模板的简化。对于一个简单的计算两个任意类
型参数之和的lambda:*/
/*
[](auto x, auto y) {
return x + y;
}
*/
//编译器会默认为它构造下面这样一个类:
class SomeCompilerSpecificName {
public:
SomeCompilerSpecificName(){}; // 构造函数只能由编译器调用
template<typename T1, typename T2>
auto operator() (T1 x, T2 y) const {
return x + y;
}
};
int main()
{
int x = 2;
double y = 3.2,i=3.4;
auto fool = [=](auto x, auto y) {return x + y; };
std::cout << typeid(fool).name() << std::endl;
std::cout << fool(x, y) << std::endl;//5
std::cout << fool(x, i) << std::endl;//5.4
return 0;
}
//下面是一个实际使用的例子
void test01() {
std::array<std::string, 2>str{ "111","222" };
std::for_each(std::begin(str), std::end(str), [](auto i) {std::cout << i << ","; });
}
void test02() {
int num[5]{ 1,2,3,4,5 };
std::for_each(std::begin(num), std::end(num), [](auto i) {std::cout << i << ","; });
}
int main()
{
test01();
test02();
return 0;
}
关于泛型lambda,它的原理我们就先不介绍了,会用即可,说起来也麻烦
如果感兴趣的话可以看看我详细写的文章
视频讲解
还是很简单的 多用即可
如果还想深入了解可以看博主的几篇别的lambda文章,比如/a4364634611/article/details/127865918