C++11-lambda表达式
1.语法形式
lambda表达式定义了一个匿名函数,其本质就是一个匿名的彷函数对象:
[ 捕获表 ](参数表) 选项 -> 返回类型 { 函数体 }
嵌入式函数
[] (int x) ->{return x*x;};//实现了小括号运算符的类对象
cout<< [] (int x) ->{return x*x;}(100)<<endl;//10000
//只能写auto
auto fun=cout<< [] (int x) ->{return x*x;};
||
||
||
class <编译器生成类名>
{
public:
int operator()(int x)const
{
return x*x;
}
private:
成员变量来自捕获表;
};
lambda表达式的值就是《编译器生成的类名》类型的对象
cout<<fun(100)<<endl;//10000
cout<<fun(200)<<endl;//40000
=========================================================
普通函数
int fun(int x){return x*x;}
cout<<fun(100)<<endl;//10000
#include <iostream> #include <vector> #include <typeinfo> #include <algorithm> using namespace std; void print (int x) { cout << x << ' '; } bool intCmp (int x, int y) { return x > y; } int main (void) { auto f1 = [] (int x = 10) -> int { return x * x; }; /* class Z4mainEUliE_ { public: int operator() (int x = 10) const { return x * x; } }; Z4mainEUliE_ f1; */ cout << typeid (f1).name () << endl; cout << f1 () << ' ' << f1 (13) << ' ' << f1 (14) << endl; cout << [] (int x = 10) -> int { return x * x; } (15)<<endl; // cout << Z4mainEUliE_ () (15) << endl; // 编译器可以根据return语句自动推导返 // 回类型,因此返回类型可以省略不写 auto f2 = [] (int x = 10) { return x * x; }; cout << f2 (16) << endl; // 列表初始化不能用于返回类型的自动推导 // auto f3 = [] (void) { return vector<int> {10, 20, 30}; }; // auto f3 = [] (void) -> vector<int> { return {10, 20, 30}; }; // 空参数表可以省略void // auto f3 = [] () -> vector<int> { return {10, 20, 30}; }; // 空参数表且返回类型可自动推导可以省略"()" auto f3 = [] { return vector<int> {10, 20, 30}; }; for (auto a : f3 ()) cout << a << ' '; cout << endl; vector<int> vi {40, 10, 50, 20, 30}; sort (vi.begin (), vi.end (), intCmp); sort (vi.begin (), vi.end (), [] (int x, int y) { return x > y; }); for_each (vi.begin (), vi.end (), print); cout << endl; for_each (vi.begin (), vi.end (), [] (int x) { cout << x << ' '; }); cout << endl; return 0; }
2.捕获列表
【】 不捕获任何外部变量
【d】 按值捕获外部变量d
【&d】 按引用捕获外部变量d
【this】 捕获this指针
【=】 按值捕获所有的外部变量,包括this指针
【&】 按引用捕获所有的外部变量,包括this指针
【=,&d】 按值捕获除d以外的外部变量(包括this指针),按引用捕获外部变量d
【&,d】 按引用捕获除d以外的外部变量(包括this指针),按值捕获外部变量d
**注意:按值捕获不可以修改变量的值,按引用捕获可以修改变量的值
mutable :在lambda中可以修改按值捕获的外部变量,这样的lambda表达式,其参数表必须显示写出,不可省略
3.不捕获任何外部变量的lambda表达式可以被隐式转换为函数原型相同的函数指针
#include <cmath> #include <iostream> using namespace std; int a = 10; class Base { protected: int b = 20; }; class Derived : public Base { public: void foo (int d = 40) { [] (int e) { cout << __FUNCTION__ << endl; cout << a << endl; // cout << b << endl; // cout << c << endl; // cout << d << endl; cout << e << endl; } (50); [d] (int e) { cout << __FUNCTION__ << endl; cout << a << endl; // cout << b << endl; // cout << c << endl; cout << d << endl; cout << e << endl; } (50); [d,this] (int e) { cout << __FUNCTION__ << endl; cout << a << endl; cout << b << endl; cout << c << endl; cout << d << endl; cout << e << endl; } (50); [=] (int e) { cout << __FUNCTION__ << endl; cout << ++a << endl; cout << ++b << endl; cout << ++c << endl; cout << /*++*/d << endl; cout << ++e << endl; } (50); [&] (int e) { cout << __FUNCTION__ << endl; cout << ++a << endl; cout << ++b << endl; cout << ++c << endl; cout << ++d << endl; cout << ++e << endl; } (50); [=,&d] (int e) { cout << __FUNCTION__ << endl; cout << ++a << endl; cout << ++b << endl; cout << ++c << endl; cout << ++d << endl; cout << ++e << endl; } (50); } private: int c = 30; }; int main (void) { cout << "输入两条直角边的长度:" << flush; int a, b; cin >> a >> b; cout << "斜边的长度:" << [] (int a, int b) { return sqrt (a * a + b * b); } (a, b) << endl; cout << "斜边的长度:" << [a, b] { return sqrt (a * a + b * b); } () << endl; /* class ??? { public: ??? (int& a, int& b) : a (a), b (b) {} int operator() (void) const { return sqrt (a * a + b * b); } private: // int const a, b; int& a, b; }; cout << "斜边的长度:" << ??? (a, b) () << endl; */ Derived obj; obj.foo (); int x = 60; auto f1 = [x] { cout << x << endl; }; ++x; f1 (); // 60 int y = 70; auto f2 = [&y] { cout << y << endl; }; ++y; f2 (); // 71 int z = 80; auto f3 = [=] { cout << /*++*/z << endl; }; auto f4 = [=] () mutable { cout << ++z << endl; }; f4 (); // 81 cout << z << endl; // 80 auto f5 = [&] { cout << ++z << endl; }; f5 (); // 81 cout << z << endl; // 81 auto f6 = [/*=*/] (int x, int y) -> int { // cout << z << endl; return sqrt (x * x + y * y); }; cout << f6 (3, 4) << endl; int (*pfun) (int, int) = f6; cout << pfun (3, 4) << endl; return 0; }