C++ lambda表示式的編譯器實現..
現在,Android已經全面轉向C++11/14標準了,看程式碼的話,很多地方變化很大,新標準真的是有點顛覆性的,感覺已經不會C++了。今天有看到lambda表示式,突然想看一下,這貨是怎麼實現的,如下,寫了個例子,分別呼叫3個lambda表示式:
很簡單定義三個lambda表示式,lambda表示式就不細說是什麼了,基本上是介紹新標準的書,都會說的很明白。這裡想看一下,具體編譯器是怎麼實現表示式的呢?第一印象,應該是表示式按照行內函數的方式實現的吧,呼叫的地方自動展開,這樣引數、捕獲列表啥的都很好實現。 簡單看一下,編譯時不優化,反彙編看一下,如下,呼叫的main函式:#include <stdlib.h> #include <stdio.h> //1. 無引數 auto hello = [] () {printf( "Hello world!\n");}; // 2. 一個引數 auto hello_int = [] (int val){ printf("the value is %d\n", val); }; int main(int argc, char **argv) { hello(); hello_int(argc); // 3. 帶捕獲列表的lambda表示式 auto lambda = [argc, argv]() {printf("param: %d, path is:%s\n", argc, argv[0]);}; lambda(); return 0; }
上面按順序呼叫的,就是程式碼中對應的三個lambda表示式。從這個反彙編看,貌似和猜想的不一樣是調了函式不是內聯展開。
紅色框住的呼叫函式[藍色是實際的符號,灰色是demangle後的,分析看這個],分別是:
這是三個過載的()操作符.. 呼叫前看到有壓入this引數,這是物件的方法呼叫,從反彙編看,是棧上建立物件,然後直接使用,使用是通過operator().. 這貨不就是函式物件麼???? OK,那就明白了,lambda表示式,編譯器自動轉換成函式物件執行。。。。 上面的例子,編譯器轉換的如下:$_0::operator()(void) $_1::operator()(int) main::$_2::operator() const(void)
這裡,lambda轉換後的符號,是編譯器自動生成的,看起來稍有點彆扭。#include <stdlib.h> #include <stdio.h> class $_0 { public: void operator() { printf( "Hello world!\n"); } }; class $_1 { public: void operator(int va) { printf("the value is %d\n", val); } }; class main::$_2 { public: main::$_2(int i, char **v): argc(i), argv(v) {} //帶捕獲列表的,不能修改捕獲列表... void operator() const { printf("param: %d, path is:%s\n", argc, argv[0]); } private: int argc; char **argv; } int main(int argc, char **argv) { $_0 hello; hello(); $_1 hello_int; hello_int(argc); main::$_2 lambda(argc, argv); lambda(); return 0; }
相關推薦
C++ lambda表示式的編譯器實現..
現在,Android已經全面轉向C++11/14標準了,看程式碼的話,很多地方變化很大,新標準真的是有點顛覆性的,感覺已經不會C++了。今天有看到lambda表示式,突然想看一下,這貨是怎麼實現的,如下,寫了個例子,分別呼叫3個lambda表示式: #include
C++ lambda表示式總結
一個lambda表示式用於建立閉包。lambda表示式與任何函式類似,具有返回型別、引數列表和函式體。與函式不同的是,lambda能定義在函式內部。lambda表示式具有如下形式 [ capture list ] ( parameter list) -> r
使用ES6新陣列方法(象C# Lambda表示式一樣寫查詢語句)
let people = [ {id: 1, name: "a", age: 12}, {id: 2, name: "b", age: 13}, {id: 3, name: "c", age: 14}, {id: 4, name: "d", age: 15}
C++ lambda表示式
1. lambda表示概念 可將lambda表示式視為包含公有operator()的匿名結構(或類),從這種意義上說,lambda表示式屬於函式物件。從上面所講到的進行分析: for_each(vectorElement.begin(), vectorElement.en
Collections.sort()方法和lambda表示式結合實現集合的排序
1.使用Collections.sort()實現集合的排序,這裡的方法具體指的是: Collections.sort(List list, Compatator c) 第一個引數:為要進行排序的集合。 第二個引數:Compatator的實現,指定排序的方式。 2
c++ lambda表示式常用的情形
lambda表示式介紹 懶,摘自msdn Capture 子句(在 C++ 規範中也稱為 lambda 引導。) 引數列表(可選)。 (也稱為 lambda 宣告符) 可變規範(可選)。 異常規
C++ lambda表示式入門
1.lambda表示式 lambda表示式 是一個函式,一個匿名函式,也就是沒有函式名的函式,為什麼不需要函式名呢,因為我們直接(一次性的)用它,嵌入式用的它,不需要其他地方用它。 也叫閉包,閉就是封閉的意思,就是其他地方都不用他,包就是函式。 lambda表示
C++ lambda表示式一個非常簡單的例子
如果我想要定義一個指向int為返回值,兩個int為引數的函式的指標,有兩種方法1: 先宣告一個函式int func(int, int);然後使用decltype推斷這個func的型別作為新定義的型別的型別typedef decltype(func) * Func1;2: 直接
C#Lambda表示式
需求 有時候我們需要傳遞一個很方法的引用,我們很確定這個方法僅僅會呼叫這一次,單獨為它建立一個方法感覺有些浪費,但是又必須用到這個方法。又或者臨時需要一個方法,但是思考半天想不出該給這個方法取什麼名字(有過這個經歷的同學握個爪)。這個時候Lambda就派上用場
C# Lambda表示式詳細總結
(一)輸入引數 在Lambda表示式中,輸入引數是Lambda運算子的左邊部分。它包含引數的數量可以為0、1或者多個。只有當輸入引數為1時,Lambda表示式左邊的一對小括弧才可以省略。輸入引數的數量大於或者等於2時,Lambda表示式左邊的一對小括弧中的多個引
C# => Lambda表示式理解
本文參考網上的部落格和找到的資料加上個人理解編寫的,主要的程式碼借鑑:http://www.cnblogs.com/knowledgesea/p/3163725.html、百度百科 希望能夠幫助理解l
C# Lambda表示式詳細
(一)輸入引數 在Lambda表示式中,輸入引數是Lambda運算子的左邊部分。它包含引數的數量可以為0、1或者多個。只有當輸入引數為1時,Lambda表示式左邊的一對小括弧才可以省略。輸入引數的數量大於或者等於2時,Lambda表示式左邊的一對小括弧中的多個引
學習C++——lambda表示式
上面三個是C++學習網站,有助於瞭解C++11的新特性。 lambda表示式(C++11) 1、介紹lambda 我們使用過的僅有兩種可呼叫物件是函式和函式指標。還有其他兩種可呼叫物件:過載了函式呼叫運算子的類,以及lambda表示式。 一個lambda表示式表示一個
C++ lambda 表示式傳遞的變數預設不可變
我遇到如下問題: int count=0; listener->onTouchMoved=[count](Touch* t,Event* e){ count++; log("onTouchMoved");
C# Lambda表示式
上一節中,我們講到:在 2.0 之前的 C# 版本中,宣告委託的唯一方法是使用命名方法。 C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表示式取代了匿名方法,作為編寫內聯程式碼的首選方式。 有一種情況下,匿名方法提供了 Lambda 表示式
c++ lambda表示式(匿名函式)的使用總結
#include <iostream> using namespace std; //[=] () mutable throw() -> int {} /** * lambda expression * “Lambda 表示式”(lambda exp
C#lambda表示式和匿名函式
lambda表示式也被稱為匿名函式,何為匿名函式? 匿名沒有真實名字,當然在C#中就是沒有函式名了,C#裡有兩種匿名函式的寫法,一種是早期推出的匿名函式,而另一種就是拉姆達(lambda)表示式了,那麼這兩種有什麼不同,分別怎麼用的,下面介紹一下. 我個人覺得吧,在寫程式碼
LINQ 通過動態生成lambda表示式,實現根據指定屬性名稱對序列進行排序
目前,對於Linq只是初步接觸,還不熟悉,做專案的時候想到一個問題,如果想要查詢任意欄位的排序結果集,該怎麼實現? 我們知道,T-SQL是非常容易解決這個問題,只要簡單通過拼接T-SQL就可以達到該效果。 那麼,Linq該怎麼實現呢? 網上查了很多資料,找到一種辦法就是通過
c++ lambda表示式捕獲變數引數
[]不捕獲任何變數 [&]捕獲外部作用域中所有變數,並作為引用在函式體重使用 [=]捕獲外部作用域中所有變數,並作為副本在函式體重使用 [=,&foo]捕獲外部作用域中所有變數,並作為副本在函式體重使用,對於foo按引用捕獲 [foo]當作副本捕獲foo,不