現代C++概覽(一): lambda表達式

正如任何一個話題,關於Modern C++的話題一旦開始,必然會引起一場HOLY WAR,支持者眾多,反對者亦也不少。支持者的原因眾多,但是歸結一點就是看到了現代C++帶來的更多可能,而反對者的原因也是各有不同,諸如帶來了更多的概念,更像Java了(對於這個原因筆者本人也是相當意外,但確實是筆者在面試時聽到候選人如此說的),C++的門檻低了等等吧。本文不討論哪種觀點的對錯,只是面對C++的迭代更新,作為C++從業人員,我們可以不更新生產環境,對新概念還有要有一定的認識。本文以C++14作為討論的基準,對於已經正式發佈的C++17進行粗略帶過。

備註

  • 由於markdown將++作為了保留字,後面全部以CXX來表示C++
  • 本文中出現的現代CXX意指CXX11及之後的標準CXX,而將CXX03/CXX98及之前的標準稱為舊標準

1. Lambda表達式

使用過其它語言(python)的同學對lambda表達式一定不陌生,lambda表達式極大地解放了程序員的體力及心智,在函數回調及異步邏輯中具有非常廣泛的用處,在舊標準中為了回調需要以預定義函數的方式來達到目的。考慮一組數據datas,使用std::foreach遍歷並處理其中的每個元素:

std::vector datas = {1, 2, 3, 4, 5, 6, 7, 8};

舊標準的寫法

// 在某個全局空間中進行定義
void procElementHandle(int element)
{
// todo something
}


// 在需要遍歷數據的地方
std::for_each(datas.cbegin(), datas.cend(), procElementHandle);

而在新標準中只需要:

std::for_each(datas.cbegin(), datas.cend(), [](int element){
// TODO something;

});

從這個示例中可以看出lambda表達式的引入不僅可以減少對全局(namespace等)空間的汙染,讓邏輯出現在它需要的地方。

不僅如此,lambda表達式也可以具有捕獲當前作用域變量的功能,格式如[capture_list],假如我們有一個需求來對datas的變量求和:

int sum = 0;
std::for_each(datas.cbegin(), datas.cend(), [&sum](int element){
sum += element;
});

另外,lambda表達式的引入也提供了在函數內定義函數以及匿名函數的功能,示例如下:

void testInnerFunc()
{
// 函數內聲明具名函數
auto innerFunc = [](int value){
cout << "inner named func " << value << endl;
};
innerFunc(9999);

// 匿名函數的使用
[](int value){
cout << "Anonymous func " << value << endl;
}(8888);
}

Lambda在現代CXX中很常用,其標準也一直處於更新之中,如返回值的自動類型推導,捕獲列表(capture list)支持別名等,具體內容可以參數lambda[cppreference],這裡有非常詳盡的介紹,這裡不再一一重複,如有問題,歡迎留言討論。

現代C++概覽(一): lambda表達式


分享到:


相關文章: