• <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 閱讀(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)

            隨筆分類

            隨筆檔案

            服務器編程

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            亚洲欧洲日产国码无码久久99| 久久中文精品无码中文字幕| 精品久久久久久亚洲精品| 99久久人妻无码精品系列蜜桃| 久久青草国产手机看片福利盒子| 久久AⅤ人妻少妇嫩草影院| 亚洲va久久久噜噜噜久久| 国产精品成人久久久久三级午夜电影 | 少妇被又大又粗又爽毛片久久黑人| 综合久久精品色| 久久精品国产免费一区| 亚洲精品第一综合99久久| 久久99久久99小草精品免视看| 无码人妻久久一区二区三区蜜桃| 久久国产精品77777| 久久久SS麻豆欧美国产日韩| 久久精品国产99国产精品| 久久久久久久综合日本亚洲| 亚洲中文字幕久久精品无码喷水| 久久国产精品二国产精品| 国产精品久久久亚洲| 亚洲精品蜜桃久久久久久| 国内精品伊人久久久影院| 久久精品国产一区二区三区| 青青热久久综合网伊人| 99久久婷婷国产综合亚洲| 久久亚洲AV成人无码国产| 色婷婷久久综合中文久久蜜桃av| 久久久精品国产| 久久久噜噜噜久久中文字幕色伊伊| 老司机午夜网站国内精品久久久久久久久 | 国产午夜精品久久久久九九| 精品久久久久久亚洲精品| 精品无码久久久久久尤物| 精品久久久久久久久午夜福利| 久久久久亚洲精品无码蜜桃| 日本久久久久亚洲中字幕 | 国产精品久久99| 9久久9久久精品| 国产精品熟女福利久久AV| 久久99亚洲综合精品首页|