• <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實現(VC & GCC)

                 foreach據說已經進了新的C++標準,不過在沒有編譯器支持以前,自己寫一個也很容易。

            (1)   foreach 標準用法: 

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


                 
                (2)VC實現

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

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

               
                (3)GCC實現

                GCC沒有內嵌支持,不過由于GCC支持typeof關鍵字, 所以實現起來也不是太難.  (有個bug, 在OwnWaterloo提醒下已經糾正)
            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有可能是一個臨時對象,或者是某個函數的返回值。為了不對容器進行復制,利用了一個不太為人所知的C++特性,就是臨時變量在存在引用時,生命期會由引用變量決定。這樣保證在進行循環時始終有效。
               
               (4)性能

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

                本文由eXile 原創,轉載請表明原貼地址。 http://www.shnenglu.com/eXile/

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

            評論

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

            用BOOST_FOREACH更好點,使用的是ISO標準C++。VC那是CLI擴展,非ISO標準.  回復  更多評論   

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

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


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


            -------- -------- 分割線 -------- --------
            是否可以考慮這樣修改?
            #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的生命周期了。  回復  更多評論   

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

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

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

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

              回復  更多評論   

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

            用宏實現的話,其類型不安全。
            在STL中已經有了for_each,肯定比自己實現的要高效。  回復  更多評論   

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

            lambda 才是王道啊,嘎嘎。  回復  更多評論   

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

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

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

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

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

            @空明流轉
            確實,沒有lambda之前,for_each沒什么意思。不過好消息是VC2010將會支持lambda.  回復  更多評論   

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

            @螞蟻終結者
            BOOST_FOREACH 的那陀實現。。。還是算了吧  回復  更多評論   

            導航

            <2025年8月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            統計

            常用鏈接

            留言簿(18)

            隨筆分類

            隨筆檔案

            服務器編程

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            成人午夜精品无码区久久| 久久香蕉一级毛片| 色欲av伊人久久大香线蕉影院| 久久99精品久久久久久不卡| 色综合合久久天天综合绕视看| 久久久久久综合一区中文字幕| 久久电影网| 亚洲精品乱码久久久久久| 99久久精品免费国产大片| 久久免费视频1| 久久99精品国产| 囯产极品美女高潮无套久久久| 国产—久久香蕉国产线看观看| 一本一本久久A久久综合精品| 久久免费小视频| 久久ZYZ资源站无码中文动漫| 精品久久久久国产免费| 少妇久久久久久被弄高潮| 亚洲国产成人久久笫一页| 久久发布国产伦子伦精品| 亚洲精品午夜国产va久久| 香港aa三级久久三级| 精品少妇人妻av无码久久| 精品久久久久久久久免费影院| 久久国产免费直播| 久久综合丝袜日本网| 久久A级毛片免费观看| 伊人 久久 精品| 色天使久久综合网天天| 久久精品这里只有精99品| 美女写真久久影院| 97久久精品国产精品青草| 97久久天天综合色天天综合色hd| 三级三级久久三级久久| 色综合久久天天综线观看| 久久艹国产| 一本久久免费视频| 久久婷婷午色综合夜啪| 一级a性色生活片久久无| 一本久久综合亚洲鲁鲁五月天| 久久国产成人|