對於stl中的演算法,我們都可以傳遞任何類別的可呼叫物件
。對於乙個物件或乙個表示式,如果可以對其使用呼叫運算子,則稱它為可呼叫的。即,如果e是乙個可呼叫的表示式,則我們可以編寫**e(args),其中args是乙個逗號分隔的乙個或多個引數的列表。
一般來說,有四種可呼叫物件:函式,函式指標,過載了函式呼叫運算子的類,以及lambda表示式。
1. 概述
乙個lambda表示式表示乙個可呼叫的**單元。我們可以將其理解為乙個未命名的內聯函式。與任何函式類似,乙個lambda具有乙個返回型別、乙個引數列表和乙個函式體。但與函式不同,lambda可能定義在函式內部。
乙個lambda的通用表示式為:
[capture list] (parameter list) -> return type
舉個簡單的例子:
auto f = ;
cout << f() << endl; //列印42
注意,忽略括號和引數列表相當於指定了空的引數列表。如果函式體為一條return語句,lambda將根據**推斷返回型別,否則型別為void。2. 傳遞引數
如函式一樣,lambda表示式也可以傳遞引數,但是不同的是,其不能有預設引數。乙個lambda呼叫的實參數目永遠要和形引數目相等。
舉個例子:
auto f = (const string &lhs, const string &rhs)
;
3. 使用捕獲列表
所謂捕獲列表,則是中括號中的引數,表示使用其所在函式中的任何區域性變數。捕獲的方式有三種:值捕獲
,引用捕獲
和隱式捕獲
。
1、空,沒有使用任何函式物件引數。
2、=,函式體內可以使用lambda所在作用範圍內所有可見的區域性變數(包括lambda所在類的this),並且是值傳遞方式(相當於編譯器自動為我們按值傳遞了所有區域性變數)。
3、&,函式體內可以使用lambda所在作用範圍內所有可見的區域性變數(包括lambda所在類的this),並且是引用傳遞方式(相當於編譯器自動為我們按引用傳遞了所有區域性變數),不過要注意是const引用。
size_t v1 = 42;
auto f = [&]() ;
// v1 = 0;
auto j = f();
cout << "end:" << j << endl;
cout << v1 << endl;
捕捉列表按引用傳遞可以修改傳遞物件的值,v1的值成了1000
4、this,函式體內可以使用lambda所在類中的成員變數。同理this的含義,按*this傳遞,可修改類成員age的值,變成了10000
5、a,將a按值進行傳遞。按值進行傳遞時,函式體內不能修改傳遞進來的a的拷貝,因為預設情況下函式是const的。要修改傳遞進來的a的拷貝,可以新增mutable修飾符。
6、&a,將a按引用進行傳遞。
7、a, &b,將a按值進行傳遞,b按引用進行傳遞。
8、=,&a, &b,除a和b按引用進行傳遞外,其他引數都按值進行傳遞。
9、&, a, b,除a和b按值進行傳遞外,其他引數都按引用進行傳遞。
如前面所提到,如果乙個lambda體包含return之外的任何語句,則編譯器假定此lambda返回void。
//錯誤示範:編譯器推斷為void,實際為int
auto f = (int i) ;
//可以修改為如下
auto f = (int i) -> int ;
1.可將bind函式看作是乙個通用的函式介面卡,它接受乙個可呼叫物件,生成乙個新的可呼叫物件來「適應」原物件的引數列表。
呼叫bind的一般形式為:
auto newcallable = bind(callable,arg_list);
2.arg_list中的引數可能包含形如_n的名字,其中n是乙個整數,這些引數是「佔位符」,表示newcallable的引數,它們佔據了傳遞給newcallable的引數的「位置」。數值n表示生成的可呼叫物件中引數的位置:_1為newcallable的第乙個引數,_2為第二個引數,以此類推
佔位符型別作用域
using namespace std::placeholders;
例子:
int f(int a, int b, int c)
//呼叫處
auto g = bind(f, _2, _1, 11);//注意:此處引數順序.._2,_1),但是bind函式引數順序是(20,10)
int k = g(10, 20);
cout << k << endl; //輸出21
實際應用中:
bool check_size(const int x, int sz)
//呼叫處
int n = 5;
//有bind函式新封裝生成的函式,其內部呼叫了check_size
auto new_check_size = bind(check_size, std::placeholders::_1, n);
auto it = find_if(v.begin(), v.end(), new_check_size);
cout << "第乙個大於n的數為:" << *it << endl;
例如cocos中也是類似實現方式:
進入cc_callback_1實現:
為了與不支援拷貝的引數繫結,bind經常和ref一起用,ref也定義在標頭檔案functional中,作用是返回乙個引用物件。
ostream &print(ostream &os, const string &s, char c)
//錯誤示範
for_each(words.begin(), words.end(), bind(print, os, _1, ' '));
//正確示範
for_each(words.begin(), words.end(), bind(print, ref(os), _1, ' '));
C 11 lambda表示式 詳解
如下圖,lambda表示式由下面幾個部分構成 c 11 的 lambda 表示式規範如下 mutable 修飾符說明 lambda 表示式體內的 可以修改 獲的變數,並且可以訪問 獲物件的 non const 方法。exception 說明 lambda 表示式是否丟擲異常 noexcept 以及丟...
C 11 lambda 表示式解析
中括號中 from 下面是各種變數擷取的選項 小括號中,就是函式引數 lambda表示式可以作為其它函式引數 1 標準格式 有箭頭 就要顯示寫明返回值型別 auto pfunc1 this void pfunc1 2 簡化格式 void 型別返回值 沒有箭頭 會預設檢測返回值型別 auto pfun...
C 11 Lambda表示式簡介
lambda簡介 capture列表 mutable說明 c 11中的lambda 表示式用於定義並建立匿名的函式物件,以簡化程式設計工作。lambda表示式一般都是從方括號開始,然後結束於花括號 主要包括五個部分 常見幾種lambda表示式形式 表示式 capture params mutable...