• <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)  編輯 收藏 引用 所屬分類: 其他
            久久久无码精品亚洲日韩蜜臀浪潮 | 一本综合久久国产二区| 亚洲欧美成人综合久久久| 老司机午夜网站国内精品久久久久久久久| 久久精品国产亚洲AV高清热 | 欧美精品丝袜久久久中文字幕| 国产成人久久激情91| 国产精品久久久久无码av| 狠狠色丁香久久婷婷综合五月 | 日韩美女18网站久久精品| 久久人人爽人爽人人爽av| 久久精品国产精品亚洲人人| 免费精品99久久国产综合精品| 久久精品国产福利国产秒| 91久久精品电影| 久久久久一级精品亚洲国产成人综合AV区| 99久久国产免费福利| 国内精品伊人久久久久影院对白| 久久精品一区二区影院| 伊人伊成久久人综合网777| 久久婷婷五月综合国产尤物app| 久久中文字幕精品| 蜜臀av性久久久久蜜臀aⅴ麻豆| 精品久久久久香蕉网| 蜜桃麻豆www久久| 亚洲国产成人精品91久久久 | 99久久综合狠狠综合久久| 国产精品欧美亚洲韩国日本久久 | 亚洲精品无码久久久久去q| 国产精品一久久香蕉产线看| 久久99精品国产99久久6| 久久综合亚洲色一区二区三区| 亚洲国产精品无码久久久蜜芽| 国产精品一区二区久久精品| 久久性生大片免费观看性| 熟妇人妻久久中文字幕| 久久福利片| 97久久久精品综合88久久| 色综合合久久天天给综看| 亚洲国产精品成人久久| 久久久精品波多野结衣|