程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 淺析C++11新特征的Lambda表達式

淺析C++11新特征的Lambda表達式

編輯:關於C++

淺析C++11新特征的Lambda表達式。本站提示廣大學習愛好者:(淺析C++11新特征的Lambda表達式)文章只能為提供參考,不一定能成為您想要的結果。以下是淺析C++11新特征的Lambda表達式正文


lambda簡介

熟習Python的法式員應當對lambda不生疏。簡略來講,lambda就是一個匿名的可挪用代碼塊。在C++11新尺度中,lambda具有以下格局:

[capture list] (parameter list) -> return type { function body }

可以看到,他有四個構成部門:

    1.capture list: 捕捉列表

    2.parameter list: 參數列表

    3.return type: 前往類型

    4.function body: 履行代碼

個中,參數列表和前往類型可以疏忽。

上面,詳細看幾個簡略的例子:

auto f1 = [] { return 1; };
auto f2 = [] () { return 2; };
cout<<f1()<<'\t'<<f2()<<endl;

捕捉列表

lambda中的捕捉列表既可以捕捉值,也能夠捕捉援用。

捕捉值:

int test_data[] = {1, 5, 9, 7, 3, 19, 13, 17};
int border = 8;
auto f3 = [border](const int &i){ if(i > border) cout<<i<<'\t'; };
for_each(begin(test_data), end(test_data), f3);
cout<<endl;

捕捉援用:

auto f4 = [&border](const int &i){ if(i > border) cout<<i<<'\t'; };
border = 6;
for_each(begin(test_data), end(test_data), f4);
cout<<endl;

經由過程輸入可以看出,lambda中起感化的border是修正後的6,證明了捕捉切實其實是是援用。

須要留意的是,在捕捉援用時,須要包管當lambda被挪用時,此援用依然有用。

捕捉列表還可以采取隱式捕捉的方法,即讓編譯器經由過程lambda的履行代碼來斷定須要捕捉哪些部分變量。

隱式捕捉可以捕捉值、援用或許二者混雜:

char space = ' ';
auto f5 = [=](const int &i){ if(i > border) cout<<i<<'\t'; };
auto f6 = [&](const int &i){ if(i > border) cout<<i<<'\t'; };
auto f7 = [&, space](const int &i){ if(i > border) cout<<i<<space; };
border = 0;
for_each(begin(test_data), end(test_data), f5);
cout<<endl;
for_each(begin(test_data), end(test_data), f6);
cout<<endl;
for_each(begin(test_data), end(test_data), f7);
cout<<endl;

這裡的f7應用的混雜情勢,可以讀作“除space捕捉值以外,其他變量均捕捉援用”。

可變lambda

當lambda須要在個中修正被值捕捉的變量的值時,須要給lambda加上mutable症結字。不然會有編譯毛病。

auto f8 = [&, space](const int &i) mutable { if(i > border) {cout<<i<<space; space='\t';} };
for_each(begin(test_data), end(test_data), f8);
cout<<endl;
cout<<1<<space<<2<<endl;

從輸入中可以看出,space在lambda f8中的值,在第一次挪用以後,就被釀成了制表符Tab;然則在lambda以外,space依然是空格。

前往類型

lambda的前往類型采取尾置前往類型的方法。普通的:

    1.lambda假如只包括return語句,則編譯器可以揣摸其前往類型,此時可以不顯示指定前往類型;

    2.不然,編譯器假定lambda前往void,而前往void的函數弗成以反悔任何詳細值,這在年夜多半情形下是個抵觸,是以須要顯示指定前往類型。

然則,經由現實測試,今朝的g++編譯器更聰慧了:關於第2點,今朝只需編譯器可以從lambda函數體中揣摸出函數的前往類型,就不須要顯式指定前往類型,例如:

auto f9 = [](const int i){if(i % 3) return i * 3; else return i;};
transform(begin(test_data), end(test_data), begin(test_data), f9);
border = 0;
for_each(begin(test_data), end(test_data), f6);
cout<<endl;

lambda代碼塊中有多個return語句,而且還有if/else語句,然則編譯器可以依據return語句揣摸出,其前往值應當是一個int類型,所以可以省略尾置前往類型。

然則,像上面這類情勢,因為編譯器在揣摸前往類型時發明了紛歧致,所以必需顯式的指定前往類型:

auto f10 = [](const int i) -> double
{if(i % 5) return i * 5.0; else return i;};
transform(begin(test_data), end(test_data), begin(test_data), f10);
for_each(begin(test_data), end(test_data), f6);
cout<<endl;

總結

    1.lambda表達式情勢: [capture list] (parameter list) -> return type { function body },個中parameter list和return type可以省略。

    2.捕捉列表可以捕捉值[val],也能夠捕捉援用[&ref]。

    3.捕捉列表還可以隱式捕捉部分變量,異樣有捕捉值[=]和捕捉援用[&]兩種方法,首次以外還可以混雜捕捉[&, val]或許[=, &ref]

    4.當lambda須要修正捕捉的值時,須要加上mutable症結字。

    4.當lambda沒法主動揣摸出前往值類型時,須要經由過程尾置前往類型的方法顯示指定。

以上就是C++11新特征之Lambda表達式的全體內容,願望本文對年夜家進修C++有所贊助。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved