c++ lambda 表达式

 

lambda表达式即匿名函数。

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

int main(){   

const int SIZE = 20;   

 int array[SIZE];   

generate_n (array, SIZE,               

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

for_each (array, array + SIZE,              

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

 return 0;

}

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的时候,原来你得这么写:
  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. }  
vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
//...
for ( auto itr = v.begin(), end = v.end(); itr != end; itr++ )
{
    cout << *itr;
}
现在有了lambda函数你就可以这么写
  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. } );  
vector<int> v;
v.push_back( 1 );
v.push_back( 2 );
//...
for_each( v.begin(), v.end(), [] (int val)
{
    cout << val;
} );
而且这么写了之后执行效率反而提高了。因为编译器有可能使用”循环展开“来加速执行过程

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值