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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM