程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++11中lambda概覽

C++11中lambda概覽

編輯:C++入門知識

雖然我對C++11沒有什麼興趣,因為C++03就已經有很多復雜的技術了。我曾經試圖把我學到的那些復雜的C++技術應用到項目中,但悲劇地發現這給團隊其他成員帶來了不小的負擔。其實也給未來一段時間的自己帶來了不小的負擔。尤其是template的應用,template代碼從外表上就一副唬人的樣子,就像即使你會Lisp,並且對Lisp中的括號不以為然,但看到滿屏幕的括號時依然內心不安。

但是稍微對C++11的一些特性做了解後,單從理論上來說,還是挺讓人有興趣的。我感覺C++11加入了不少函數式語言的特性和思想,這是我感興趣的最大理由。今天來看看C++11中的lambda。

C++03中,在使用STL容器時,或者我自己寫的類中,常有遍歷的需求,本來寫個functor傳進去就可以,但是這functor偏偏寫的很惡心。因為你需要局部定義一個結構體,重載operator(),並且,如果這個operator()依賴這個functor構建時的上下文信息,你得往這個結構體裡塞入若干成員,當然還得讓構造函數的參數變得越來越長。最後,在包含你這個functor使用以及結構體定義的這個代碼塊,在其代碼格式上就變得非常奇怪。如果你像我一樣常這樣應用,一定深有感觸。

然後,C++11來了,C++11中的lambda,就我個人而言,其語法還是非常現代的。來看看其文法形式(截自N2550):

lambda-expression:
      lambda-introducer lambda-parameter-declaration compound-statement
lambda-introducer:
      [ lambda-capture ]
lambda-capture:
      capture-default
      capture-list
      capture-default , capture-list
capture-default:
      &
      =
capture-list:
      capture
      capture-list , capture
capture:
      identifier
      & identifier
      this
lambda-parameter-declaration:
      ( lambda-parameter-declaration-list ) exception-specification lambda-return-type-clause
lambda-parameter-declaration-list:
      lambda-parameter
      lambda-parameter , lambda-parameter-declaration-list
lambda-parameter:
      decl-specifier-seq declarator
lambda-return-type-clause:
      -> type-id
翻譯過來大致就是這樣的形式:

[capture] (parameter) spec ->return-type { body }
capture就是這個lambda實現裡可以訪問的這個lambda定義時作用域裡的變量列表,就像Lua裡的upvalue。其實我覺得這個才是lambda最方便程序員的地方,一般的函數式語言其實不需要顯示聲明這個列表,直接引用這些變量即可。後面的部分都比較好理解,parameter就是這個lambda被調用時的形參列表,return-type就是這個lambda的返回值類型,body自然就是這個lambda的實現。至於spec,主要就是指定異常及body裡對capture裡的變量的使用權限。一個例子:

vector<int> ints;
ints.push_back(99);
ints.push_back(100);
ints.push_back(101);
int threhold = 100;
int sum = 0;
for_each(ints.begin(), ints.end(),
        [threhold, &sum] (int v) {
            if (v >= threhold) ++ sum;
            });
printf("%d\n", sum);
capture使用了threhold和sum,但是threhold僅使用其值,而sum則使用了其引用,通過結果可以看出lambda中改變了sum的值。

C++11正在被越來越多的編譯器支持,也越來越支持得更好。這裡有個表,羅列了C++11的各個特性在各個編譯器上的支持情況,僅供查閱(以上示例代碼測試於vs2010,即MSVC10.0)。

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