一文读懂 C++11 中的匿名函数(也称lambda函数、lambda表达式)

目录

一、作用

二、格式

三、capture 闭包

四、lambda 表达式作为参数

五、最常用例子一看必懂


一、作用

实际开发中非常常用,对于短小精悍的函数没必要都提取出来,原地定义一个匿名函数即可。

二、格式

[capture](parameters) -> return-type { body }

能省略的项都可以省略,甚至()都可以省略,但是[]{}不可省略哦,举例:

[](int x, int y) -> int { int z = x + y; return z; }
[](int x, int y) { return x + y; } // 隐式返回类型
[](int& x) { ++x; }   // 没有return语句 -> lambda 函数的返回类型是'void'
[]() { ++global_x; }  // 没有参数,仅访问某个全局变量
[] { ++global_x; }     // 与上一个相同,省略了()

三、capture 闭包

capture 也可以叫做闭包,作用是引用 lambda 表达式之外的变量。这个机制运行这些变量按值或引用捕获。说白了,就是里面用的变量可以不是形参,而是外部变量。

[capture] 格式举例:

[]        // 未定义变量.试图在Lambda内使用任何外部变量都是错误的.
[x, &y]   // x 按值捕获, y 按引用捕获.
[&]       // 用到的任何外部变量都隐式按引用捕获
[=]       // 用到的任何外部变量都隐式按值捕获
[&, x]    // x显式地按值捕获. 其它变量按引用捕获
[=, &z]   // z按引用捕获. 其它变量按值捕获

实际用法举例:

std::vector<int> some_list;
int total = 0;
for (int i=0;i<5;++i) some_list.push_back(i);
std::for_each(begin(some_list), end(some_list), [&total](int x) 
{
    total += x;
});

形参是x,但 total 是外部变量,以引用方式被捕获,这样就可以改变外部 total 的值。如果想捕获的外部变量太多,可以直接 [&, ...]。再举例:

std::vector<int> some_list;
int total = 0;
int value = 5;
std::for_each(begin(some_list), end(some_list), [&, value, this](int x) 
{
  total += x * value * this->some_func();
});

这里 total 没有显式列举在闭包里,但闭包里有 &,就可以了。外部的 value 和 this 是按值捕获,this 也只能按值捕获。

四、lambda 表达式作为参数

一般用 auto 类型,自己写对应类型比较麻烦:

auto a_lambda_func = [](int x) { /*...*/ };
void (*func_ptr)(int) = a_lambda_func;
func_ptr(4); //calls the lambda.

五、最常用例子一看必懂

比如定义一个简单的类:

// Definition for an interval.
struct Interval {
    int start;
    int end;
    Interval() : start(0), end(0) {}
    Interval(int s, int e) : start(s), end(e) {}
};

那么 vector<Interval> intervals 排序怎么排?比如 [[10,30],[20,60],[80,100],[150,180]] 按第一个从小到大排序。lamda表达式排上用场:

auto lam = [](Interval a, Interval b) {
    return a.start < b.start;
};
sort(intervals.begin(), intervals.end(), lam);

以上部分参考优秀博客:

C++11中的匿名函数(lambda函数,lambda表达式) - 缘来是梦 - 博客园 (cnblogs.com)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值