C++11新标準引入lambda表達式,主要部分如下:
[捕獲清單](參數)->type{函數體},使用尾置傳回類型,其中可以忽略參數與傳回類型,但要儲存捕獲清單與函數體,使用調用運算符調用,可在(參數)後添加mutable限定符使值捕獲的資料可在函數體裡修改。
使用lambda表達式時,編譯器會産生未命名類的未命名對象,且有一個調用運算符成員函數,實際使用時會調用該調用運算符成員函數。該未命名類不包含預設構造函數、指派運算符、預設析構函數,而是否包含預設的拷貝、移動構造函數與捕獲資料成員類型有關。
[捕獲清單]
表示外部捕獲的資料,會将外部資料通過構造函數傳入未命名類裡,可使用值傳遞與引用傳遞,值傳遞:auto Lambda = [intVal](){cout << intVal << endl;}; Lambda();,預設intVal為const類型,且該調用運算符是const成員函數,不可修改intVal,如果需要修改則在(參數)後添加限定符mutable:
auto Lambda = [intVal]()mutable{cout << ++intVal << endl;}; Lambda();,此時intVal可修改,且調用運算符成員函數是非const函數。值傳遞不會改變外部資料。
引用傳遞:auto Lambda = [&intVal](){cout << ++intVal << endl;}; Lambda();,引用傳遞是否被修改取決于intVal是否為const類型,如果被修改則會同時修改外部資料。
可使用隐式的值、引用傳遞,其捕獲的資料可通過編譯器在函數體的推導得出:auto Lambda = [=,&intVal](){cout << (data+intVal) << endl;}; Lambda();,其中data為隐式值傳遞;auto Lambda = [&](){cout << (data-intVal) << endl; func();}; Lambda();,其中data,intVal都是隐式引用傳遞,同時調用了func函數。如果使用隐式傳遞則要求=、&要在捕獲清單的首位置,同時之後的顯式捕獲不可為隐式捕獲的傳遞方式。
注:如果是在類内使用并調用類内資料,則可以使用[=]、[&]、[this]方式隐式或顯式捕獲this并使用類内成員,如果是類靜态成員可以直接使用而不用捕獲。
(參數)
接收外部參數,與普通調用類似:auto Lambda = [](int val){cout << ++val << endl;}; Lambda(1);。匿名函數是可調用對象,可作為比較函數傳入:
// main.cpp
#include <iostream>
#include <algorithm>
using std::cout;
using std::ends;
using std::sort;
using std::string;
using std::begin;
using std::end;
int main()
{
string arr[] = {"123","12345","1233","1233345"};
sort(begin(arr),end(arr),[]
(const string &s1,const string &s2)
{
return s1.size() > s2.size(); // 按照字元串的大小逆序排序
}
);
for (const auto &each : arr)
{
cout << each << ends;
}
return 0;
}
// main.cpp
#include <iostream>
using std::cout;
using std::ends;
int main()
{
auto Lambda = [](int choice)->char
{
if (choice == 0)
{
return 0x41; // 'A'
}
else
{
return '1';
}
};
cout << Lambda(0) << ends;
return 0;
}