1.Lambda的语法
所谓lambda是一份功能定义式,可以被定义于语句(statement)或表达式(expression)内部,因此可以将lambda当作inline函数使用。[]叫做introducer,可以在内部指明一个所谓的capture,用来在lambda内部访问nonstatic外部对象
- 最简单的lambda
int main()
{
//定义一个lambda,但没有进行调用
[] {
std::cout << "hello lambda!" << endl;
};
//定义一个lambda并进行调用
[] {
std::cout << "hello lambda1!" << endl;
}();
//或者将它传给一个对象
auto l = [] {
std::cout << "hello lambda1!" << endl;
};
l(); //调用
cout << sizeof(l) << endl; //answer = 1
return 0;
}
在lambda introducer和lambda body之间,可以指明参数或mutable,或一份异常明细或attribute specifier以及返回类型。这些是可有可无的,如果出现了,参数所需的小括号就必须出现
lambda语法
1.[...] {...}
2.[...] (...) mutable throwSpec ->retType {...}
lambda可以拥有参数,指明在小括号内
auto l = [] (const string& s) {
cout << s << endl;
};
l("hello");
lambda不可以是template,必须始终指明所有类型。
lambda也可以返回某物,但不需要指明返回类型,该类型会根据返回值被推导出来。
int main()
{
// 1.lambda可以返回某物,不用指明类型,可以自动推导
auto l = [] {
return 123;
};
int ans = l();
cout << ans << endl;
// 2.也可以指明一个返回类型
auto l2 = []() -> double { //注意()
return 123;
};
double ans2 = l2();
cout << ans2 << endl;
return 0;
}
2.Capture(用以访问外部作用域)
在lambda最开始的方括号内,可以指明一个capture用来处理外部作用域内未被传递为实参的数据:
- [=]意味着外部作用域以by value方式传递给lambda,因此当这个lambda被定义时,你可以读取所有可读数据,但不能修改
- [&]意味着外部作用域以by reference方式传递给lambda,可以对所有数据进行修改。
- 也可以个别指明为by value或者by reference,混合使用。也可以[=, &y]取代[x, &y],意思是y以by reference传递,其他实参以by value传递。
int main()
{
int x = 0;
int y = 42;
auto l = [x, &y] {
// x以by value形式传递, y以by reference方式传递
cout << "x: " << x << endl; //0
cout << "y: " << y << endl; //42
//x++; //error
y++; //ok
};
l();
cout << "final y: " << y << endl; //43
return 0;
}
为了得到passing by reference和value的混合体,可以声明lambda为mutable。意思是以by value传递,但是可以在lambda中修改传入的值。
int main()
{
int x = 0;
int y = 42;
auto l = [x, &y]() mutable {
// x以by value形式传递, y以by reference方式传递
cout << "x: " << x << endl; //0
cout << "y: " << y << endl; //42
x++; //ok
y++; //ok
};
l();
cout << "final x: " << x << endl; //0
cout << "final y: " << y << endl; //43
return 0;
}
3.Lambda的类型
lambda的类型,是一个不具名的function object(或者说functor)。每个lambda表达式的类型是独一无二的。因此如果想根据该类型声明对象,可以借助template或者auto,如果实在需要写下这个类型,可以借助decltype().例如将lambda作为hash function或ordering准则或sorting准则传给容器。
也可以使用C++STL提供的function<>class template指明一个一般化类型给functional programming使用。这个class template提供了"明确指出函数的返回类型为lambda"的唯一办法。
#include <iostream>
#include <functional>
using namespace std;
function<int(int, int)> returnLambda() {
return [](int x, int y) {
return x * y;
};
}
int main()
{
auto lf = returnLambda();
cout << lf(5, 7) << endl;
return 0;
}