c++ lambda 表达式

来源:互联网 发布:西服品牌知乎 编辑:程序博客网 时间:2024/05/17 04:36

 

lambda表达式即匿名函数。

1.下面看一个简单的lambda表达式的例子:(随机产生数组的值,然后输出)

int main(){   

constint SIZE=20;   

 int array[SIZE];   

generate_n (array, SIZE,               

                  [](){return rand()%30+1;});   

for_each (array, array+ SIZE,              

            [](int a){ cout<< a<<" ";});       

 return0;

}

2.lambda的构成

  1. lambda-introducer (捕获字段)
  2. lambda-parameter-declaration-list (变量列表)
  3. mutable-specification (捕获的变量可否修改)
  4. exception-specification (异常设定)
  5. lambda-return-type-clause (返回类型)
  6. compound-statement (函数体)

外部变量的捕获规则

默认情况下,即捕获字段为 [] 时,lambda表达式是不能访问任何外部变量的,即表达式的函数体内无法访问当前作用域下的变量。

如果要设定表达式能够访问外部变量,可以在 [] 内写入 & 或者 = 加上变量名,其中 & 表示按引用访问,= 表示按值访问,变量之间用逗号分隔,比如 [=factor, &total] 表示按值访问变量 factor,而按引用访问 total。

下面是各种变量截取的选项:
  • [] 不截取任何变量
  • [&} 截取外部作用域中所有变量,并作为引用在函数体中使用
  • [=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用
  • [=, &foo]   截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用
  • [bar]   截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量
  • [this]            截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。

 

参数列表

lambda表达式的参数列表基本和函数的一致,不过有如下限制:

  1. 参数列表不能有默认参数
  2. 不能是可变参数列表
  3. 所有的参数必须有个变量名

如果你不提供 mutable-specification, exception-specification, 以及 lambda-return-type-clause,参数列表是也可以省略的。如下面的表达式:

int main(){   int x = 4;   int y = 5;   int z = [=] { return x + y; }();}

能否修改捕获的变量

如果在参数列表后加上了 mutable,则表示表达式可以修改按值捕获的外部变量的拷贝。

异常设置

和函数一样,可以用 throw 来限定表达式能够抛出哪些异常。

返回类型

如果设置返回类型,你需要在类型名前面加上 ->。如果你只有一个返回语句的话,返回类型可以省略,编译器将会为你做出判断。

函数体

lambda表达式的函数体和普通函数大致相同。


 

Lambda函数和STL



lambda函数的引入为STL的使用提供了极大的方便。比如下面这个例子,当你想便利一个vector的时候,原来你得这么写:
[cpp] view plaincopyprint?
  1. vector<int> v;  
  2. v.push_back( 1 );  
  3. v.push_back( 2 );  
  4. //...   
  5. for ( auto itr = v.begin(), end = v.end(); itr != end; itr++ )  
  6. {  
  7.     cout << *itr;  
  8. }  
现在有了lambda函数你就可以这么写
[cpp] view plaincopyprint?
  1. vector<int> v;  
  2. v.push_back( 1 );  
  3. v.push_back( 2 );  
  4. //...   
  5. for_each( v.begin(), v.end(), [] (int val)  
  6. {  
  7.     cout << val;  
  8. } );  
而且这么写了之后执行效率反而提高了。因为编译器有可能使用”循环展开“来加速执行过程

 

 

 

0 0