• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-91  評論-137  文章-0  trackbacks-0

            Lambda表達式提供了匿名函數這個概念,可以使您在一個函數中書寫另一個匿名的函數體

            先來看下如何在VC2010中書寫Lambda表達式

            [捕捉項表](參數表)->返回類型{函數體}
            捕捉項表中在變量前添加&操作符表示捕捉引用,添加=表示捕捉值
            參數表與"->"和后面的返回類型是可選的編譯器會由函數體內的return語句判斷返回類型,當返回類型很復雜時編譯器無法判斷,則必須手動給出!

            下面舉個簡單的例子:
             1 #include <stdio.h>
             2 
             3 int main()
             4 {
             5     int a = 100;
             6     [a]{
             7         printf("%d\n",a);
             8     }();
             9     return 0;
            10 }
            然后在VS2010提示中編譯它:cl /FAs a.cpp
            /FAs參數指定了輸出匯編文件a.asm.

            然后我們來看一下它生成的匯編代碼:
              1 ; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 
              2 
              3     TITLE    D:\a.cpp
              4     .686P
              5     .XMM
              6     include listing.inc
              7     .model    flat
              8 
              9 INCLUDELIB LIBCMT
             10 INCLUDELIB OLDNAMES
             11 
             12 PUBLIC    ??R<lambda0>@?A0x428ab923@@QBEXXZ        ; `anonymous namespace'::<lambda0>::operator()
             13 PUBLIC    ??0<lambda0>@?A0x428ab923@@QAE@ABH@Z        ; `anonymous namespace'::<lambda0>::<lambda0>
             14 PUBLIC    _main
             15 ; Function compile flags: /Odtp
             16 ; File d:\a.cpp
             17 _TEXT    SEGMENT
             18 $T3875 = -8                        ; size = 4
             19 _a$ = -4                        ; size = 4
             20 _main    PROC
             21 
             22 4    : {
             23 
             24     push    ebp
             25     mov    ebp, esp
             26     sub    esp, 8
             27 
             28 5    :     int a = 100;
             29 
             30     mov    DWORD PTR _a$[ebp], 100            ; 00000064H
             31 
             32 6    :     [a]{
             33 7    :         printf("%d\n",a);
             34 8    :     }();
             35 
             36     lea    eax, DWORD PTR _a$[ebp]
             37     push    eax
             38     lea    ecx, DWORD PTR $T3875[ebp]
             39     call    ??0<lambda0>@?A0x428ab923@@QAE@ABH@Z    ; `anonymous namespace'::<lambda0>::<lambda0>
             40     mov    ecx, eax
             41     call    ??R<lambda0>@?A0x428ab923@@QBEXXZ    ; `anonymous namespace'::<lambda0>::operator()
             42 
             43 9    :     return 0;
             44 
             45     xor    eax, eax
             46 
             47 10   : }
             48 
             49     mov    esp, ebp
             50     pop    ebp
             51     ret    0
             52 _main    ENDP
             53 ; Function compile flags: /Odtp
             54 _TEXT    ENDS
             55 ;    COMDAT ??0<lambda0>@?A0x428ab923@@QAE@ABH@Z
             56 _TEXT    SEGMENT
             57 _this$ = -4                        ; size = 4
             58 __A$ = 8                        ; size = 4
             59 ??0<lambda0>@?A0x428ab923@@QAE@ABH@Z PROC        ; `anonymous namespace'::<lambda0>::<lambda0>, COMDAT
             60 ; _this$ = ecx
             61 
             62 8    :     }();
             63 
             64     push    ebp
             65     mov    ebp, esp
             66     push    ecx
             67     mov    DWORD PTR _this$[ebp], ecx
             68     mov    eax, DWORD PTR _this$[ebp]
             69     mov    ecx, DWORD PTR __A$[ebp]
             70     mov    edx, DWORD PTR [ecx]
             71     mov    DWORD PTR [eax], edx
             72     mov    eax, DWORD PTR _this$[ebp]
             73     mov    esp, ebp
             74     pop    ebp
             75     ret    4
             76 ??0<lambda0>@?A0x428ab923@@QAE@ABH@Z ENDP        ; `anonymous namespace'::<lambda0>::<lambda0>
             77 _TEXT    ENDS
             78 PUBLIC    ??_C@_03PMGGPEJJ@?$CFd?6?$AA@            ; `string'
             79 EXTRN    _printf:PROC
             80 ;    COMDAT ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
             81 CONST    SEGMENT
             82 ??_C@_03PMGGPEJJ@?$CFd?6?$AA@ DB '%d', 0aH, 00H        ; `string'
             83 ; Function compile flags: /Odtp
             84 CONST    ENDS
             85 ;    COMDAT ??R<lambda0>@?A0x428ab923@@QBEXXZ
             86 _TEXT    SEGMENT
             87 _this$ = -4                        ; size = 4
             88 ??R<lambda0>@?A0x428ab923@@QBEXXZ PROC            ; `anonymous namespace'::<lambda0>::operator(), COMDAT
             89 ; _this$ = ecx
             90 
             91 6    :     [a]{
             92 
             93     push    ebp
             94     mov    ebp, esp
             95     push    ecx
             96     mov    DWORD PTR _this$[ebp], ecx
             97 
             98 7    :         printf("%d\n",a);
             99 
            100     mov    eax, DWORD PTR _this$[ebp]
            101     mov    ecx, DWORD PTR [eax]
            102     push    ecx
            103     push    OFFSET ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
            104     call    _printf
            105     add    esp, 8
            106 
            107 8    :     }();
            108 
            109     mov    esp, ebp
            110     pop    ebp
            111     ret    0
            112 ??R<lambda0>@?A0x428ab923@@QBEXXZ ENDP            ; `anonymous namespace'::<lambda0>::operator()
            113 _TEXT    ENDS
            114 END
            115 
            由匯編代碼可以看到先為Lambda函數生成了一個匿名對象,然后調用了()的操作符重載函數調用這個匿名函數.

            由此我們得出結論:調用一個匿名函數并沒有調用一個存在的函數或是一個類的成員函數快,只是書寫更方便罷了.

            然后我們修改一下代碼,將匿名函數先賦給一個匿名函數指針,然后調用.
             1 #include <stdio.h>
             2 
             3 int main()
             4 {
             5     int a = 100;
             6     auto ptr = [a]{
             7         printf("%d\n",a);
             8     };
             9     ptr();
            10     return 0;
            11 }
            編譯后得到代碼:
              1 ; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.30319.01 
              2 
              3     TITLE    D:\a.cpp
              4     .686P
              5     .XMM
              6     include listing.inc
              7     .model    flat
              8 
              9 INCLUDELIB LIBCMT
             10 INCLUDELIB OLDNAMES
             11 
             12 PUBLIC    ??R<lambda0>@?A0x428ab923@@QBEXXZ        ; `anonymous namespace'::<lambda0>::operator()
             13 PUBLIC    ??0<lambda0>@?A0x428ab923@@QAE@ABH@Z        ; `anonymous namespace'::<lambda0>::<lambda0>
             14 PUBLIC    _main
             15 ; Function compile flags: /Odtp
             16 ; File d:\a.cpp
             17 _TEXT    SEGMENT
             18 _ptr$ = -8                        ; size = 4
             19 _a$ = -4                        ; size = 4
             20 _main    PROC
             21 
             22 4    : {
             23 
             24     push    ebp
             25     mov    ebp, esp
             26     sub    esp, 8
             27 
             28 5    :     int a = 100;
             29 
             30     mov    DWORD PTR _a$[ebp], 100            ; 00000064H
             31 
             32 6    :     auto ptr = [a]{
             33 7    :         printf("%d\n",a);
             34 8    :     };
             35 
             36     lea    eax, DWORD PTR _a$[ebp]
             37     push    eax
             38     lea    ecx, DWORD PTR _ptr$[ebp]
             39     call    ??0<lambda0>@?A0x428ab923@@QAE@ABH@Z    ; `anonymous namespace'::<lambda0>::<lambda0>
             40 
             41 9    :     ptr();
             42 
             43     lea    ecx, DWORD PTR _ptr$[ebp]
             44     call    ??R<lambda0>@?A0x428ab923@@QBEXXZ    ; `anonymous namespace'::<lambda0>::operator()
             45 
             46 10   :     return 0;
             47 
             48     xor    eax, eax
             49 
             50 11   : }
             51 
             52     mov    esp, ebp
             53     pop    ebp
             54     ret    0
             55 _main    ENDP
             56 ; Function compile flags: /Odtp
             57 _TEXT    ENDS
             58 ;    COMDAT ??0<lambda0>@?A0x428ab923@@QAE@ABH@Z
             59 _TEXT    SEGMENT
             60 _this$ = -4                        ; size = 4
             61 __A$ = 8                        ; size = 4
             62 ??0<lambda0>@?A0x428ab923@@QAE@ABH@Z PROC        ; `anonymous namespace'::<lambda0>::<lambda0>, COMDAT
             63 ; _this$ = ecx
             64 
             65 8    :     };
             66 
             67     push    ebp
             68     mov    ebp, esp
             69     push    ecx
             70     mov    DWORD PTR _this$[ebp], ecx
             71     mov    eax, DWORD PTR _this$[ebp]
             72     mov    ecx, DWORD PTR __A$[ebp]
             73     mov    edx, DWORD PTR [ecx]
             74     mov    DWORD PTR [eax], edx
             75     mov    eax, DWORD PTR _this$[ebp]
             76     mov    esp, ebp
             77     pop    ebp
             78     ret    4
             79 ??0<lambda0>@?A0x428ab923@@QAE@ABH@Z ENDP        ; `anonymous namespace'::<lambda0>::<lambda0>
             80 _TEXT    ENDS
             81 PUBLIC    ??_C@_03PMGGPEJJ@?$CFd?6?$AA@            ; `string'
             82 EXTRN    _printf:PROC
             83 ;    COMDAT ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
             84 CONST    SEGMENT
             85 ??_C@_03PMGGPEJJ@?$CFd?6?$AA@ DB '%d', 0aH, 00H        ; `string'
             86 ; Function compile flags: /Odtp
             87 CONST    ENDS
             88 ;    COMDAT ??R<lambda0>@?A0x428ab923@@QBEXXZ
             89 _TEXT    SEGMENT
             90 _this$ = -4                        ; size = 4
             91 ??R<lambda0>@?A0x428ab923@@QBEXXZ PROC            ; `anonymous namespace'::<lambda0>::operator(), COMDAT
             92 ; _this$ = ecx
             93 
             94 6    :     auto ptr = [a]{
             95 
             96     push    ebp
             97     mov    ebp, esp
             98     push    ecx
             99     mov    DWORD PTR _this$[ebp], ecx
            100 
            101 7    :         printf("%d\n",a);
            102 
            103     mov    eax, DWORD PTR _this$[ebp]
            104     mov    ecx, DWORD PTR [eax]
            105     push    ecx
            106     push    OFFSET ??_C@_03PMGGPEJJ@?$CFd?6?$AA@
            107     call    _printf
            108     add    esp, 8
            109 
            110 8    :     };
            111 
            112     mov    esp, ebp
            113     pop    ebp
            114     ret    0
            115 ??R<lambda0>@?A0x428ab923@@QBEXXZ ENDP            ; `anonymous namespace'::<lambda0>::operator()
            116 _TEXT    ENDS
            117 END
            118 
            和上面的直接調用并無差別,因為一個匿名函數含有一個隱藏的對象.

            應此__asm call ptr;這樣調用是錯誤的!因為你無法用call指令來調用一個對象的成員函數.
            posted on 2011-02-17 16:32 lwch 閱讀(2673) 評論(0)  編輯 收藏 引用 所屬分類: 其他
            亚洲国产婷婷香蕉久久久久久| 久久只有这里有精品4| 国色天香久久久久久久小说| 久久国语露脸国产精品电影| 亚洲人成精品久久久久 | 久久久艹| 久久精品麻豆日日躁夜夜躁| 亚洲嫩草影院久久精品| 亚洲级αV无码毛片久久精品| 久久精品国产一区| 亚洲v国产v天堂a无码久久| 久久婷婷国产麻豆91天堂| 伊人久久大香线蕉综合网站| 情人伊人久久综合亚洲| 亚洲精品无码久久久久久| 欧美性猛交xxxx免费看久久久| 久久久久久久97| 精品综合久久久久久97| 香蕉99久久国产综合精品宅男自 | 久久人妻少妇嫩草AV蜜桃| 精品久久久久久成人AV| 99久久国产综合精品女同图片| 国产精品欧美久久久久天天影视| 久久无码人妻一区二区三区午夜| 久久精品国产欧美日韩| 国产高潮国产高潮久久久91 | 一本一道久久综合狠狠老| 久久亚洲av无码精品浪潮| 人人狠狠综合久久亚洲88| 99精品久久精品| 久久精品国产清高在天天线| 欧美日韩精品久久久免费观看| 久久久久久毛片免费看| 国内精品久久久久久麻豆 | 四虎国产精品免费久久5151| 新狼窝色AV性久久久久久| 精品久久久久久国产| 青青草原精品99久久精品66| 亚洲中文字幕久久精品无码喷水 | 久久青青草视频| 久久久久久曰本AV免费免费|