• <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 尹東斐 閱讀(1775) 評論(1)  編輯 收藏 引用 所屬分類: 深入探索 boost::lambda 系列

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

            常用鏈接

            留言簿(4)

            隨筆檔案

            文章分類

            文章檔案

            相冊

            好友博客

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            久久精品国产99久久久| 婷婷久久综合九色综合九七| 午夜精品久久久久久毛片| 久久er99热精品一区二区| 91久久精品国产免费直播| 久久久久免费视频| 久久棈精品久久久久久噜噜| 青青青伊人色综合久久| 午夜精品久久久内射近拍高清| 久久久精品国产sm调教网站| 久久国产综合精品五月天| 久久精品无码专区免费东京热| 久久精品国产只有精品66| 久久99国产乱子伦精品免费| 亚洲精品成人网久久久久久| 伊人久久精品线影院| 久久综合香蕉国产蜜臀AV| 国产精品乱码久久久久久软件 | 久久久久国色AV免费看图片| 少妇久久久久久久久久| 四虎国产精品免费久久| 爱做久久久久久| 青青草原综合久久| 久久久久久久99精品免费观看| 久久久精品国产免大香伊 | 7777久久久国产精品消防器材| 久久精品女人天堂AV麻| 国内精品久久久久久中文字幕| 久久久一本精品99久久精品66| 国产美女亚洲精品久久久综合| 亚洲国产日韩欧美久久| 亚洲国产天堂久久综合| 国产精品美女久久福利网站| 日本精品久久久久久久久免费| 欧美午夜A∨大片久久| 91精品国产91久久久久久蜜臀| 久久久久国产精品| 久久久久亚洲AV无码专区网站 | 夜夜亚洲天天久久| 91久久福利国产成人精品| 国产免费久久精品丫丫|