• <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>

            eXile 的專欄

            最簡單的foreach實現(xiàn)(VC & GCC)

                 foreach據(jù)說已經(jīng)進了新的C++標(biāo)準(zhǔn),不過在沒有編譯器支持以前,自己寫一個也很容易。

            (1)   foreach 標(biāo)準(zhǔn)用法: 

            std::vector<int> vec;
            foreach(int i,  vec) {
                std::cout  
            <<  i;
            }


                 
                (2)VC實現(xiàn)

                 在最新的VC版本中原來已經(jīng)有了類似于foreach的支持,改個名字就行了:

            #define foreach(var, container)   for each(var in containter)

               
                (3)GCC實現(xiàn)

                GCC沒有內(nèi)嵌支持,不過由于GCC支持typeof關(guān)鍵字, 所以實現(xiàn)起來也不是太難.  (有個bug, 在OwnWaterloo提醒下已經(jīng)糾正)
            template <typename C> struct foreach_helper {
                typename C::const_iterator it, end;
                foreach_helper (
            const C& c) : it(c.begin()), end(c.end()) {}
            };


            #define RANDOM_VAR(name, line)     RANDOM_VAR_(name, line)
            #define RANDOM_VAR_(name, line)    name ## line


            #define foreach(var, container)  \
            __typeof__(container) 
            const&   RANDOM_VAR(_con_, __LINE__) = container; \
            for (foreach_helper <__typeof__(container)> _fh_(RANDOM_VAR(_con_, __LINE__)); _fh_.it != _fh_.end; ++_fh_.it) \
            for (var = *_fh_.it;; __extension__ ({break;}))

               
                這里有一個特殊的考慮,就是container有可能是一個臨時對象,或者是某個函數(shù)的返回值。為了不對容器進行復(fù)制,利用了一個不太為人所知的C++特性,就是臨時變量在存在引用時,生命期會由引用變量決定。這樣保證在進行循環(huán)時始終有效。
               
               (4)性能

                  我分別使用GCC和VC9進行了測試(優(yōu)化選項都使用O2),結(jié)果表明使用foreach和普通的iterator 遍歷幾乎沒有差別。不過gcc的遍歷性能要明顯好于VC9 (用個具有中國特色的結(jié)論,就是大約要好五倍),我的測試當(dāng)然很粗略,不值得相信。

                本文由eXile 原創(chuàng),轉(zhuǎn)載請表明原貼地址。 http://www.shnenglu.com/eXile/

            posted on 2009-05-08 01:25 eXile 閱讀(3879) 評論(10)  編輯 收藏 引用 所屬分類: C/C++

            評論

            # re: 最簡單的foreach實現(xiàn)(VC & GCC)[未登錄] 2009-05-08 12:20 tom

            用BOOST_FOREACH更好點,使用的是ISO標(biāo)準(zhǔn)C++。VC那是CLI擴展,非ISO標(biāo)準(zhǔn).  回復(fù)  更多評論   

            # re: 最簡單的foreach實現(xiàn)(VC & GCC) 2009-05-08 12:42 OwnWaterloo

            -------- -------- 引 -------- --------
            這里有一個特殊的考慮,就是container有可能是一個臨時對象,或者是某個函數(shù)的返回值。為了不對容器進行復(fù)制,利用了一個不太為人所知的C++特性,就是臨時變量在存在引用時,生命期會由引用變量決定。這樣保證在進行循環(huán)時始終有效。
            -------- -------- 引 -------- --------


            函數(shù)返回值就是臨時對象的一種吧?
            這個特性更準(zhǔn)確描述應(yīng)該是:
            const 引用可以綁定到一個臨時對象上,
            臨時對象的生命周期將延長至const引用超出作用域。
            臨時對象原本的生命周期僅到產(chǎn)生臨時對象的完整表達式結(jié)束。


            -------- -------- 分割線 -------- --------
            是否可以考慮這樣修改?
            #define foreach(var, container) \
            { \
            /... \
            }

            ——1是可以避免臨時對象的生命周期被延長到不需要的地方

            ——2是可以避免一個bug:
            #define RANDOM_VAR(name, line) name ## line
            這個宏不會以你想想中的樣子工作。

            至少要改成:
            #define RANDOM_VAR(name, line) RANDOM_VAR_(name,line)
            // 交給另一個宏
            #define RANDOM_VAR_(name,line) name##line
            // 才能啟動rescan機制,將__LINE__展開


            ——3. 如果讓foreach_helper有一個到container的const引用, 也就不需要單獨的RANDOM_VAR去提升container的生命周期了。  回復(fù)  更多評論   

            # re: 最簡單的foreach實現(xiàn)(VC & GCC) 2009-05-08 12:46 OwnWaterloo

            同時…… 非常不明白 ……
            為什么很多C++程序員(甚至是許多老手)都喜歡使用下劃線開頭的標(biāo)識符……
            這是個非常不好的習(xí)慣……  回復(fù)  更多評論   

            # re: 最簡單的foreach實現(xiàn)(VC & GCC) 2009-05-08 13:53 eXile

            @OwnWaterloo
            謝謝提醒,RANDOM_VAR的定義確實不對,要改成你說的樣子.
            不過你說的加大括號或者foreach_helper加container引用的辦法,是不行的。
            至于,為什么使用下劃線開頭,正是因為這種命名方法不常用,所會才會避免偶然和其它變量重名的情況,一般也就是僅限于宏中使用。

              回復(fù)  更多評論   

            # re: 最簡單的foreach實現(xiàn)(VC & GCC) 2009-05-08 14:53 Wealth

            用宏實現(xiàn)的話,其類型不安全。
            在STL中已經(jīng)有了for_each,肯定比自己實現(xiàn)的要高效。  回復(fù)  更多評論   

            # re: 最簡單的foreach實現(xiàn)(VC & GCC) 2009-05-08 16:54 空明流轉(zhuǎn)

            lambda 才是王道啊,嘎嘎。  回復(fù)  更多評論   

            # re: 最簡單的foreach實現(xiàn)(VC & GCC) 2009-05-08 17:07 空明流轉(zhuǎn)

            @Wealth
            你從哪兒看出不安全?不高效?又從哪兒看出for_each和foreach是等價的了?  回復(fù)  更多評論   

            # re: 最簡單的foreach實現(xiàn)(VC & GCC) 2009-05-08 18:19 螞蟻終結(jié)者

            至于生命周期,大可不必用RANDOM_VAR這種方式,還是建議看一下BOOST_FOREACH
              回復(fù)  更多評論   

            # re: 最簡單的foreach實現(xiàn)(VC & GCC) 2009-05-08 21:31 eXile

            @空明流轉(zhuǎn)
            確實,沒有l(wèi)ambda之前,for_each沒什么意思。不過好消息是VC2010將會支持lambda.  回復(fù)  更多評論   

            # re: 最簡單的foreach實現(xiàn)(VC & GCC) 2009-05-08 21:33 eXile

            @螞蟻終結(jié)者
            BOOST_FOREACH 的那陀實現(xiàn)。。。還是算了吧  回復(fù)  更多評論   

            導(dǎo)航

            <2014年9月>
            31123456
            78910111213
            14151617181920
            21222324252627
            2829301234
            567891011

            統(tǒng)計

            常用鏈接

            留言簿(18)

            隨筆分類

            隨筆檔案

            服務(wù)器編程

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            欧美无乱码久久久免费午夜一区二区三区中文字幕 | 国内高清久久久久久| A级毛片无码久久精品免费| 久久久无码精品亚洲日韩蜜臀浪潮| 国产99久久精品一区二区| 色天使久久综合网天天| 狠狠综合久久AV一区二区三区| 久久精品aⅴ无码中文字字幕不卡| 人人狠狠综合88综合久久| 无码国内精品久久人妻| 亚洲精品久久久www| 久久99精品国产麻豆蜜芽| WWW婷婷AV久久久影片| 亚洲精品蜜桃久久久久久| 99久久99久久精品国产片| 久久99精品综合国产首页| 精品国产91久久久久久久| 无码精品久久久天天影视| 麻豆亚洲AV永久无码精品久久| 中文成人无码精品久久久不卡| 国产亚洲精久久久久久无码| 久久久久国产成人精品亚洲午夜| 国产亚州精品女人久久久久久 | 久久久久久九九99精品| 久久久久久亚洲精品无码| 99久久无码一区人妻a黑| 偷窥少妇久久久久久久久| 久久精品aⅴ无码中文字字幕不卡| 伊人久久综在合线亚洲2019| 久久99国产精品尤物| 精品国产乱码久久久久久呢 | 青青青青久久精品国产h久久精品五福影院1421 | 久久久久国产一区二区| 91精品国产综合久久精品| 嫩草伊人久久精品少妇AV| 狠狠综合久久综合88亚洲| 一级A毛片免费观看久久精品| 久久精品国产精品亚洲艾草网美妙| 99久久精品国产高清一区二区| 久久综合狠狠综合久久| 国产精品无码久久久久久|