• <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://m.shnenglu.com/eXile/

            posted on 2009-05-08 01:25 eXile 閱讀(3877) 評論(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 的那陀實現。。。還是算了吧  回復  更多評論   

            導航

            <2013年10月>
            293012345
            6789101112
            13141516171819
            20212223242526
            272829303112
            3456789

            統計

            常用鏈接

            留言簿(18)

            隨筆分類

            隨筆檔案

            服務器編程

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            国产精品久久久久影院嫩草| 精品多毛少妇人妻AV免费久久| 手机看片久久高清国产日韩| 伊人久久成人成综合网222| 久久久久久久久波多野高潮| 久久精品aⅴ无码中文字字幕重口 久久精品a亚洲国产v高清不卡 | 久久妇女高潮几次MBA| 色综合久久久久综合体桃花网| 99精品久久精品| 99久久免费国产精品特黄| 久久99热只有频精品8| 久久亚洲国产成人精品无码区| 久久精品天天中文字幕人妻| 久久夜色精品国产www| 国产午夜免费高清久久影院| 武侠古典久久婷婷狼人伊人| 69久久精品无码一区二区| 色婷婷综合久久久久中文字幕| 久久免费高清视频| 久久99精品久久久久婷婷| 97精品伊人久久大香线蕉| 国产激情久久久久影院小草 | 久久久国产精品福利免费| 日本亚洲色大成网站WWW久久 | 国产午夜精品久久久久九九电影 | 国产Av激情久久无码天堂| 中文精品99久久国产| 国产精品欧美久久久久无广告| 日韩乱码人妻无码中文字幕久久| 香蕉99久久国产综合精品宅男自 | 2020久久精品亚洲热综合一本| 国内精品久久久久久99蜜桃 | 国产精品美女久久福利网站| 久久精品国产亚洲Aⅴ香蕉| 亚洲一本综合久久| 精品久久香蕉国产线看观看亚洲| 国产精品一区二区久久| 99久久免费国产精品热| 国产精品久久久久影视不卡| 久久夜色精品国产亚洲| 成人国内精品久久久久影院|