• <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>
            posts - 18,  comments - 104,  trackbacks - 0

            看看之前做到哪里了:實現了一個賦值的lambda表達式。

            這次來看看怎么添加新的運算進去,然后再說點關于表達式的問題,為以后的擴展打下理論基礎。

            先看看之前的代碼吧,

             1 template <typename _U>
             2 struct op
             3 {
             4     op(_U i)
             5         : _i(i)
             6     {}
             7 
             8     _U _i;
             9 
            10     template<typename _T>
            11     _T& operator()(_T& i)
            12     {
            13         i = _i;
            14     }
            15 };
            16 
            17 struct place_holder
            18 {
            19     template <typename _T>
            20     op<_T> operator=(_T i)
            21     {
            22         return op<_T>(i)
            23     }
            24 };
            25 
            26 place_holder _1;
            27 
            28 vector<double> v;
            29 for_each(v.begin(), v.end(), _1 = 3);

            現在,要在這個基礎上,添加新的操作進來,比如說operator+=吧。要怎么做呢?

            1.  place_holder要重載operator+= 才可以,因為place_holder的主要任務就是替我們生成一個仿函數。
            2.  要有相應的仿函數來真正的做 += ,也就是說在仿函數的operator()里面,要有真正干活的操作。

            好了,開始吧, 先看看實現,然后在解釋。

             1 struct op
             2 {
             3     op(int i)
             4         : _i(i)
             5     {}
             6 
             7     int _i;
             8 
             9     int operator()(int& i)
            10     {
            11         return i = _i;
            12     }
            13 };
            14 
            15 struct op1
            16 {
            17     op1(int i)
            18         : _i(i)
            19     {}
            20 
            21     int _i;
            22 
            23     int operator()(int& i)
            24     {
            25         return i += _i;
            26     }
            27 };
            28 
            29 struct place_holder
            30 {
            31     op operator=(int i)
            32     {
            33         return op(i);
            34     }
            35 
            36     op1 operator+=(int i)
            37     {
            38         return op1(i);
            39     }
            40 };
            41 
            42 place_holder _1;
            43 
            44 void main()
            45 {
            46 
            47     vector<int> v;
            48     v.push_back(12);
            49     v.push_back(1342);
            50     v.push_back(23);
            51 
            52     for_each(v.begin(), v.end(), _1 += 3);
            53 }

            好了,現在+=操作已經被支持了。多么簡單呀。來看看都做了些什么:

            1.  給place_holder增加了一個operator+=函數, operator+= 返回op1類型的仿函數。
            2.  增加了一個op1的仿函數(類模板),用來真正的執行 += 的運算。

            當編譯器看到  _1 += 3 時,去找到 place_holder::operator+=, 然后把模板參數推導成 int,返回一個 op1<int> 對象。
            在for_each里面,就調用op1<int>::operator+=了。

            當然也可以這么用:

            1 double x = 0.0;
            2 (_1 += 10.4)(x);

            到這里大家想必已經可以照貓畫虎,實現其他操作了吧。但是當實現的操作多起來的時候,新的問題就來了,比如想要個 _1 = _2 + 3.0 的時候呢?看看下面的代碼:

             1 _1 = _2 + 3.0    //lambda表達式
             2 
             3 void fun(double& lhs, const double& rhs)  //相同功能函數
             4 {
             5     lhs = rhs + 3.0;
             6 }
             7 
             8 struct op
             9 {
            10     template <typename _T>
            11     _T operator(_T& lhs, const _T& rhs)
            12     {
            13         lhs = rhs + 3.0;
            14     }
            15 };
            16 

            看看lambda表達式為我們省了多少代碼!當然我不是為了說這個而寫這么長段代碼,我想說,那個op是我們的最終目標,能實現嗎?不能!因為在op里面直接出現了3.0,按照前面的慣例,應該在op里面有一個成員變量來保存3.0,不是嗎?根本問題不在這里。

            仔細想想我們到底在做什么,我們在用template的技法,“編譯”表達式。
            place_holder其實就像C++的表達式,op就像匯編語言,通過template技法,把place_holder的表達式“編譯”成用op組成的操作,op是可以直接被C++運行的仿函數。也就是說是一個從lambda語法到C++語法的編譯器,但是這個編譯器靠template技法實現,由真正的C++編譯器進行模板推導,最后“編譯”成C++的仿函數。所以一句話就是:

            用template技法實現的從lambda語法到C++語法的“編譯器”。

            所以根本問題在于op的這種寫法沒有辦法擴展,難道對于每種連起來的操作,都分別寫一個op嗎(比如_1 = (_2 + 3.0) * (_2 - 3.0),C++中表達式無數,要是每種都要寫個op,那要lambda何用 )?op相當于匯編,只要幾個簡單的運算就OK,關鍵在于按照place_holder的表達,把op組合起來。

            下一篇準備介紹一下boost::tuple,和表達式編譯,因為它們是實現lambda的關鍵武器。
            posted on 2009-02-22 22:11 尹東斐 閱讀(1767) 評論(1)  編輯 收藏 引用 所屬分類: 深入探索 boost::lambda 系列

            FeedBack:
            # re: 深入探索 boost::lambda 系列(三)
            2011-06-16 17:48 | lucida
            lambda里面想構造一個class A的實例,A帶構造參數的,怎么寫  回復  更多評論
              
            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            常用鏈接

            留言簿(4)

            隨筆檔案

            文章分類

            文章檔案

            相冊

            好友博客

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            看全色黄大色大片免费久久久| 人妻少妇久久中文字幕一区二区| 国产精品久久久久9999| 久久这里只精品国产99热| 欧美777精品久久久久网| 久久99精品国产麻豆不卡| 久久天天躁夜夜躁狠狠| 99久久综合狠狠综合久久止| 久久综合九色综合久99| 久久久噜噜噜久久熟女AA片 | 性高湖久久久久久久久AAAAA| 亚洲人成网亚洲欧洲无码久久| 欧美一区二区精品久久| 久久久久久久97| 亚洲午夜无码久久久久小说| 精品一区二区久久| 亚洲AV日韩精品久久久久久| 午夜精品久久久久久影视777| 国产精品无码久久综合| 久久久久亚洲AV无码观看| 国产精品美女久久久久av爽| 久久国产精品77777| 亚洲中文字幕无码久久2020| 亚洲精品国产综合久久一线| 久久精品国产亚洲AV不卡| 亚洲一区二区三区日本久久九| 日韩人妻无码一区二区三区久久| 日韩十八禁一区二区久久| 国产亚州精品女人久久久久久| 丰满少妇人妻久久久久久| 午夜人妻久久久久久久久| 久久精品卫校国产小美女| 亚洲欧美一级久久精品| 久久无码人妻精品一区二区三区| 国产精品久久久久乳精品爆| 99久久国产免费福利| 久久精品国产亚洲麻豆| 色综合久久综精品| 麻豆国内精品久久久久久| 久久久久亚洲爆乳少妇无| 国产精品久久久久久久久久影院|