C++ 中的匿名函数(lambda表达式)

问题引入

使用std::sort函数对自定义类型排序时,我们需要传入一个比较函数作为参数。该比较函数只需要使用一次,但占有一个全局命名域中的名字,而且非常短,短到不需要名字就知道它的作用。这很浪费命名资源。

解决问题

使用匿名函数(又名lambda表达式)可以解决这个问题,它允许我们在另一个函数中定义一个匿名的函数。这不仅节约了名字,还让一个函数的定义尽可能靠近它的使用处。

c++中匿名函数的形式如下:

[ captureClause ] ( parameters ) -> returnType
{
    statements;
}

captureClause不在本博客范围内,若有兴趣自行搜索。
parameters表示该函数的参数。
returnType表示该函数的返回值类型。(若省略"->returnType",则返回值默认为auto)
statements为函数体语句。

例子

将数组中数字按绝对值升序排列。

#include <bits/stdc++.h>

using namespace std;

int n;
vector<int> b;

static auto _ = []() {
    std::ios::sync_with_stdio(false);
    cin.tie(nullptr);
    return nullptr;
}(); //Here () means we call this lambda expression

int main() {
    cin >> n;
    b.clear();
    b.resize(n);
    for (int i = 0; i < n; ++i) {
        cin >> b[i];
    }
    sort(b.begin(), b.end(),
         [](const int a, const int b) { return abs(a) < abs(b); });          //Here is  our lambda, no capture clause
    for (int i = 0; i < n; ++i) {
        cout << b[i] << " ";
    }
}

输入:

9
-3 -5 9 1 2 -7 -8 4 -6

输出:

1 2 -3 4 -5 -6 -7 -8 9

备注

注意到上述代码定义了一个名字是_(下划线)的函数的静态lambda表达式。最后的括号表示调用这个表达式。一般在OJ中经常使用这个表达式来加速输入输出。

更深刻的理解——lambda表达式的类型

事实证明,lambda表达式不存在显式的类型。编译器会为它生成一个不暴露给我们的特定类型。其实lambda表达式不是函数,是重载了()操作符的对象,只是表现和函数相似。

posted @ 2021-09-21 21:06  capacito  阅读(995)  评论(0编辑  收藏  举报