問題引入
使用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表達式不是函數,是重載了()操作符的對象,只是表現和函數相似。