auto func = [capture] (params) opt -> ret { func_body; }; [捕获列表] (形参列表) mutable 异常列表-> 返回类型{ 函数体 } 捕获列表:定义lambda函数所在的作用域中的指定变量可以在lambda函数中使用
其中func是可以当作lambda表达式的名字,作为一个函数使用,capture是捕获列表,params是参数表,opt是函数选项(mutable之类), ret是返回值类型,func_body是函数体。 各项的含义:
捕获列表:捕获外部变量,捕获的变量可以在函数体中使用,可以省略,即不捕获外部变量。
形参列表:和普通函数的形参列表一样。可省略,即无参数列表
mutable:mutable 关键字,如果有,则表示在函数体中可以修改捕获变量,根据具体需求决定是否需要省略。
异常列表:noexcept / throw(…),和普通函数的异常列表一样,可省略,即代表可能抛出任何类型的异常。
返回类型:和函数的返回类型一样。可省略,如省略,编译器将自动推导返回类型。
函数体:代码实现。可省略,但是没意义。
lambda表达式允许捕获一定范围内的变量: [] 不捕获任何变量 [&] 引用捕获,捕获外部作用域所有变量,在函数体内当作引用使用 [=] 值捕获,捕获外部作用域所有变量,在函数内内有个副本使用 [=, &a] 值捕获外部作用域所有变量,按引用捕获a变量 [a] 只值捕获a变量,不捕获其它变量 [this] 捕获当前类中的this指针
C++ 11
#include<iostream>
#include<functional>
using namespace std;
int main()
{
auto basiclambda01=[](){cout<<"hello lambda"<<endl;} ;
basiclambda01();
auto basiclambda02=[](int a, int b)->int{
cout<<"param and ret lambda"<<endl;
return a+b;
};
int result = basiclambda02(3,4);
cout<<result<<endl;
cout<<basiclambda02(4,5)<<endl;
int data = 2;
auto basicLambda03 = [&data](){
cout<<"inside basicLambda03 = " <<++data<<endl;
};
basicLambda03();
cout<<"outside basicLambda03 = " << data<<endl;
auto basicLambda04 = [data]()mutable {
cout<<"inside basicLambda04 = " <<++data<<endl;
};
basicLambda04();
cout<<"outside basicLambda04 = " << data<<endl;
auto basicLambda05 = [&](){
cout<<"inside basicLambda05 = " <<++data<<endl;
};
basicLambda05();
cout<<"outside basicLambda05 = " << data<<endl;
auto basicLambda06 = [=]()mutable{
cout<<"inside basicLambda06 = " <<++data<<endl;
};
basicLambda06();
cout<<"outside basicLambda06 = " << data<<endl;
return 0;
}
C++ 14
#include <iostream>
#include <memory>
#include <utility>
int main() {
auto important = std::make_unique<int>(1);
auto add01 = [v1 = 1, v2 = std::move(important)](int x, int y) -> int {
return x+y+v1+(*v2);
};
std::cout << add01(3,4) << std::endl;
auto add02 = [](auto x, auto y) {
return x+y;
};
std::cout <<add02(1, 2)<< std::endl;
std::cout <<add02(1.1, 2.2)<< std::endl;
return 0;
}
c++11 中 auto 关键字不能够用在参数表里,这是因为这样的写法会与模板的功能产生冲突。 但是 Lambda 表达式并不是普通函数,所以 Lambda 表达式并不能够模板化。 这就为我们造成了一定程度上的麻烦:参数表不能够泛化,必须明确参数表类型。
幸运的是,这种麻烦只存在于 C++11 中,从 C++14 开始, Lambda 函数的形式参数可以使用 auto 关键字来产生意义上的泛型:
|