您好,登錄后才能下訂單哦!
本篇文章為大家展示了C++11新引入的lambda表達式怎么用,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
ISO C++ 11 標準的一大亮點是引入Lambda表達式。基本語法如下:
[capture list] (parameter list) ->return type { function body }
簡單的講一下各個部分的作用
1.[capture list]捕獲列表,捕獲到函數體中,使得函數體可以訪問
2.(parameter list)參數列表,用來表示lambda表達式的參數列表
3.->return type函數返回值 {function body}就是函數體
lambda表達式可以理解為一個匿名函數(但本質并不是),如果要使用lambda表達式聲明的函數,需要給他“命名”
lambda表達式可以表示閉包,因為本身就是這個類
閉包是指可以包含自由變量的代碼塊 (未綁定到特定的對象:舉個栗子std::function就可以產生一個對象,或者一個未指向任何函數的函數指針)
閉包講的通俗一些有以下幾點
1.自帶上下文的函數,閉包可以儲存運行時需要的上下文,這樣就可以在上下文不存在的時候還可以使用閉包(變量a生命周期到了被銷毀,但是在閉包中還可以拿來用)
2.可以把閉包看成一個重載了operator()的類,帶有狀態的意思就可以解釋成通過this指針使用成員變量
3.capture list就是lambda表達式實現閉包的方式
簡單使用的例子
--------------------------------------------------------------------------------
C++11為auto提供了新的功能,如他的名字一般,現在可以看成自動適應類型,可以適應多數類型
使用auto來代替變量的類型,前提是被明確類型的初始化變量初始化的,可以使用auto關鍵字
auto f = [](){}; auto f = [](int a, int b)->int {return a + b; }; f(1, 2);//需要這么使用
只要是函數類型就都可以使用這個lambda表達式
typedef int(*FUNC)(int a, int b); int main() { FUNC a= [](int a, int b) {return a + b; }; printf("%d\n", a(1, 2)); }
聲明函數的方法都可以接收不帶捕獲列表的lambda表達式
typedef std::function<int(int a, int b)> FUNC; int main() { FUNC a= [](int a, int b) {return a + b; }; printf("%d\n", a(1, 2)); }
--------------------------------------------------------------------------------
lambda表達式中capture list的用法
int func(int a, int b, std::function<int(int, int)> f) { return f(a, b); } int a=1; int b=2; int c=3; int d = func(a, b, [a, &b](int m, int n) { printf("a = %d\n", a); // a是通過值傳遞捕獲,mutable只在函數體內修改有效 printf("b = %d\n", b); // b是引用傳遞捕獲,mutable可以對外部b造成影響 //printf("c = %d\n", c); // c不可訪問 return m + n; }); typedef int(*FUNC)(int m, int n,std::function<int(int ,int )> f); void test() { FUNC oho; int a = 10; int b = 20; auto func = [&a, &b](int m, int n) {printf("a:%d b:%d\n", a, b); return m + n; }; }
1.[]空。沒有使用任何函數對象參數。
2.[=]。函數體內可以使用Lambda所在作用范圍內所有可見的局部變量(包括Lambda所在類的this),并且是值傳遞方式(相當于編譯器自動為我們按值傳遞了所有局部變量)。
3.[&]。函數體內可以使用Lambda所在作用范圍內所有可見的局部變量(包括Lambda所在類的this),并且是引用傳遞方式(相當于編譯器自動為我們按引用傳遞了所有局部變量)。
4.[this]。函數體內可以使用Lambda所在類中的成員變量。
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按值進行傳遞外,其他參數都按引用進行傳遞。&符號的位置必須在頭一個
當你想改變通過傳值方式捕捉的變量的時候就要添加mutable
[a, &b, &b2](int m, int n)mutable {a *= 2; return m*n; }:
--------------------------------------------------------------------------------
lambda表達式的其他用法
class A { public: A(); ~A(); void test() { auto f = [this](int m, int n) {printf("%d\n", a); }; } private: int a; };
lambda表達式本質是一種閉包類型,雖然他可以賦值給函數指針,但是只限于在捕獲列表為空的時候,當捕獲列表有值的時候,應該使用auto來接收lambda表達式,或者用std::function也是可以的
main::__l2::<lambda_eb7b0a89c14bee3d2620c108ffb635c6>
//這是一個lambda表達式在VS2015環境下顯示的類型,不用auto用什么來接收調用他呢?
本質來說lambda表達式之間是不允許賦值的
auto a = [](int m, int n) {return m + n; }; auto b = [](int m, int n) {return m - n; }; a = b;
操作非法,因為閉包類型不允許使用賦值操作符,但是函數指針可以,也就是可以有下面的操作
typedef int(*FUNC)(int a, int b); int main() { FUNC a = [](int a, int b) {return a + b; }; FUNC b = [](int a, int b) {return a + b; }; a = b; return 0; }
std::function之間也是可以賦值的,他就可以辦到有capture list的lambda表達式進行賦值
typedef std::function<int(int,int)> FUNC; int m = 10; int n = 20; FUNC a = [m, n](int a, int b){printf("%d\n", m); return a + b; }; FUNC b = [m, n](int a, int b){return a + b; }; b = a; b(1, 2); //執行結果是可以把m打印出來的
上述內容就是C++11新引入的lambda表達式怎么用,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。