• <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 閱讀(3886) 評論(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 的那陀實現。。。還是算了吧  回復  更多評論   

            導航

            <2009年3月>
            22232425262728
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            統計

            常用鏈接

            留言簿(18)

            隨筆分類

            隨筆檔案

            服務器編程

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            国产亚洲美女精品久久久2020| 久久久久久九九99精品| 国产精品一区二区久久精品无码| 办公室久久精品| 亚洲成色WWW久久网站| 九九99精品久久久久久| 欧美日韩中文字幕久久久不卡 | 久久AV高清无码| 久久影视国产亚洲| 97久久精品人妻人人搡人人玩| 精品久久久久久无码中文字幕| 伊人久久大香线蕉综合Av| 久久精品成人免费国产片小草| 蜜臀久久99精品久久久久久小说| 久久久噜噜噜久久| 国产成人精品久久| 精品国产VA久久久久久久冰| 亚洲精品成人网久久久久久| 国产亚洲美女精品久久久| 成人综合伊人五月婷久久| 无码国产69精品久久久久网站| 性高湖久久久久久久久AAAAA| 国产A级毛片久久久精品毛片| 国产成人久久AV免费| 久久久精品人妻一区二区三区蜜桃| 亚洲国产精品一区二区三区久久 | 18禁黄久久久AAA片| 麻豆精品久久精品色综合| 国产精品无码久久综合| 久久婷婷五月综合色奶水99啪| 久久精品国产99国产精品导航| 一本色道久久88综合日韩精品| 久久综合狠狠综合久久97色| 国产精品久久久久久久久久免费| 国产午夜免费高清久久影院| 国产成年无码久久久久毛片| 97久久精品无码一区二区| 国产成人无码精品久久久免费| 国产精品美女久久久久AV福利| 久久男人AV资源网站| 久久国产精品无|