What is a lambda expression in C++11?

本文介绍了C++11中引入的Lambda表达式的使用方法。Lambda表达式简化了匿名函数的创建过程,使代码更加简洁易读。文章通过具体的示例说明了如何定义Lambda表达式,并解释了如何指定返回类型以及如何捕获外部变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

The problem

C++ includes useful generic functions like std::for_each and std::transform, which can be very handy. Unfortunately they can also be quite cumbersome to use, particularly if the functor you would like to apply is unique to the particular function.


   
#include < algorithm > #include < vector > namespace { struct f { void operator ()( int ) { // do something } }; } void func(std::vector < int >& v) { f f; std::for_each(v.begin(), v.end(), f); }

If you only use f once and in that specific place it seems overkill to be writing a whole class just to do something trivial and one off.

In C++03 you might be tempted to write something like the following, to keep the functor local:


   
void func2(std::vector < int >& v) { struct { void operator ()( int ) { // do something } } f; std::for_each(v.begin(), v.end(), f); }

however this is not allowed, f cannot be passed to a template function in C++03.

The new solution

C++11 introduces lambdas allow you to write an inline, anonymous functor to replace the struct f. For small simple examples this can be cleaner to read (it keeps everything in one place) and potentially simpler to maintain, for example in the simplest form:


   
void func3(std::vector < int >& v) { std::for_each(v.begin(), v.end(), []( int ) { /* do something here */ }); }

Lambda functions are just syntactic sugar for anonymous functors.

Return types

In simple cases the return type of the lambda is deduced for you, e.g.:


   
void func4(std::vector < double >& v) { std::transform(v.begin(), v.end(), v.begin(), []( double d) { return d < 0.00001 ? 0 : d; } ); }

however when you start to write more complex lambdas you will quickly encounter cases where the return type cannot be deduced by the compiler, e.g.:


   
void func4(std::vector < double >& v) { std::transform(v.begin(), v.end(), v.begin(), []( double d) { if (d < 0.0001 ) { return 0 ; } else { return d; } }); }

To resolve this you are allowed to explicitly specify a return type for a lambda function, using -> T:


   
void func4(std::vector < double >& v) { std::transform(v.begin(), v.end(), v.begin(), []( double d) -> double { if (d < 0.0001 ) { return 0 ; } else { return d; } }); }
"Capturing" variables

So far we've not used anything other than what was passed to the lambda within it, but we can also use other variables, within the lambda. If you want to access other variables you can use the capture clause (the [] of the expression), which has so far been unused in these examples, e.g.:


   
void func5(std::vector < double >& v, const double & epsilon) { std::transform(v.begin(), v.end(), v.begin(), [epsilon]( double d) -> double { if (d < epsilon) { return 0 ; } else { return d; } }); }

You can capture by both reference and value, which you can specify using = and &:

  • [&epsilon] capture by reference
  • [&, epsilon] specify that the default way of capturing is by reference and what we want to capture
  • [=, &epsilon] capture by value by default, but for epsilon use reference instead

The generated operator() is const by default, with the implication that captures will be const when you access them by default. This has the effect that each call with the same input would produce the same result, however you can mark the lambda as mutable to request that the operator() that is produced is not const.

转载于:https://my.oschina.net/jacobin/blog/193736

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值