结合侯捷老师的视频 和cpprefenrence 所写的测试和用法
逐个运行 即可了解其用法
#include <iostream>
#include <set>
using namespace std;
void test()
{
[] {
cout << "hello lambda" << endl;
}(); //print hello
auto l = [] {
cout << "hello lambda" << endl;
};
l(); //print hello;
//[capture] (params) opt->ret { body; }; capture 捕获列表 params事参数表,
//opt是函数选项,ret是返回值 body是函数体
//[...](...)mutable throwspec ->retType{...} 3个只要出现一个 需要有小括号
auto f = [](int a) -> int { return a + 1; };
std::cout << f(1) << std::endl; // 输出
}
void test1()
{
//mutable 是指内部id可以变化 ++id 没有的话 ++id error(测试发现有传入引用参数也可以不加mutable),按照编程习惯还是加上为好
int id = 0;
auto f = [id]()mutable { //pass by value
cout << "id = " << id << endl;
++id;
};
id = 42;
f();//0
f();//1
f();//2
cout << id << endl;//42
}
void test2()
{
int id = 0;
auto f = [&id](int param = 0)mutable { //pass by value
cout << "id = " << id << endl;
cout << param << endl;
++id;
};
id = 42;
f();//42 0
f();//43 0
f();//44 0
cout << id << endl;//445
}
void test3()
{
int id = 0;
auto f = [&id](int param = 0)mutable->int{ //返回类型可以省略,但是类型不同时需要写出(编译器无法推导)
cout << id << endl;
++id;
int a = 3;
static int b = 3;
return param + a + b;
};
id = 42;
cout << f(3) << endl;//42 9
}
void test4()
{
/***********************************************************************
lambda表达式可以通过捕获列表捕获一定范围内的变量:
·[]不捕获任何变量。
·[&]捕获外部作用域中所有变量,并作为引用在函数体中使用(按引用捕获)。
·[=]捕获外部作用域中所有变量,并作为副本在函数体中使用(按值捕获)。
·[=, & foo]按值捕获外部作用域中所有变量,并按引用捕获foo变量。
·[bar]按值捕获bar变量,同时不捕获其他变量。
·[this]捕获当前类中的this指针,让lambda表达式拥有和当前类成员函数同样的访问权限。如果已经使用了&或者 = ,就默认添加此选项。捕获this的目的是可以在lamda中使用当前类的成员函数和成员变量。
******************************************************************************************************************************/
int id = 0;
int id2 = 3;
auto f = [=,&id](int param = 0)mutable->int {
id++;
id2++;
return param;
};
cout << f(3) << endl;//3
cout << id2 << endl;//3 按值捕获 id2不变
cout << id << endl;//1 按引用捕获 id改变
}
struct Point { double x, y; };
struct PointCmp {
bool operator() (const Point &lhs, const Point &rhs) {
return hypot(lhs.x, lhs.y) < hypot(rhs.x, rhs.y);
}
};
void test5()
{
std::set<Point, PointCmp> z = { {2, 5}, {3, 4}, {1, 1} };
z.insert({ 1, -1 }); // 这会插入失败,不会报error,因为 1,-1 的长度等于 1,1
for (auto& p : z) std::cout << '(' << p.x << ',' << p.y << ") ";
std::cout << '\n';
auto PointLam = [](const Point &lhs, const Point &rhs) {
return hypot(lhs.x, lhs.y) < hypot(rhs.x, rhs.y);
};
std::set<Point, decltype(PointLam)> x(PointLam) ;
x.insert({ 1, -1 });
x.insert({ 2,5 });
x.insert({ 3,4 });
x.insert({ 0,1 });
for (auto& p : x) std::cout << '(' << p.x << ',' << p.y << ") ";
}
int main()
{
//test(); 最简单的lambdas
//test1();//pass by value
//test2();//pass by reference
//test3();//lambdas就是一个匿名函数 返回值 声明定义 静态都可以
//test4();//lambdas 捕获 列表
test5();//lambdas 应用于set
}
|