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

            The Coder

            I am a humble coder.

              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
              4 隨筆 :: 4 文章 :: 9 評論 :: 0 Trackbacks

            在調用算法函數的時候,有時候會把不同序列的迭代器當成同一序列使用。
            下面提供避免這樣錯誤的一種機制。
            本內容來自TCPL(特別版)

            有時候,我們會犯這樣的錯誤,把兩個不同序列的迭代器去構成一個序列了。比如:

            void ?f(list < string >& ?fruit,?list < string >& ?citrus)
            {
            ?typedef?list
            < string > ::const_iterator?LI;

            ?LI?p1?
            = ?find(fruit.begin(),?citrus.end(),? " apple " );? // ?error,?不在同一序列
            ?LI?p2? = ?find(fruit.begin(),?fruit.end(),? " apple " );
            ?LI?p3?
            = ?find(citrus.begin(),?citrus.end(),? " pear " );
            ?LI?p4?
            = ?find(p2,?p3,? " peach " );? // ?這個更加隱蔽。
            }

            這里Bjarne Stroustrup給出一個解決問題的途徑。其關鍵就是用整個容器代替x.begin, x.end()的輸入。
            這樣,我們要封裝兩個東西,1、find()函數。 2、begin(),end()

            利用重載,封裝find函數。

            template < class ?In,? class ?T > ?
            In?find(Iseq
            < In > ?r,? const ?T & ?v)?? // 通過重載機制,得到這個find的擴充版本。
            {
            ????
            return ?find(r.first,?r.second,?v);? // 標準庫中的find
            };

            ?

            利用對偶,封裝迭代器。
            首先,我們構造一個Iseq以保證迭代器是統一序列成對輸入的。

            template < class ?In > struct ?Iseq:? public ?pair < In,?In > {
            ????Iseq(In?i1,?In?i2):?pair
            < In,?In > (i1,?i2){}
            };

            ?

            接著構造一個協助函數,直接傳遞容器。

            template < class ?C > Iseq < typename?C::iterator > ?iiseq(C & ?c)? // C為容器
            {
            ????
            return ?Iseq < typename?C::iterator > (c.begin(),?c.end());
            }


            這樣,我們可以利用上面的機制,來避免所提出的錯誤。

            void ?f(list < string >& ?fruit,?list < string >& ?citrus)
            {
            ?typedef?list
            < string > ::const_iterator?LI;

            ?LI?p1?
            = ?find(iiseq(fruit),? " apple " );?
            ?LI?p2?
            = ?find(iiseq(citrus),? " apple " );
            ?LI?p3?
            = ?find(citrus.begin(),?citrus.end(),? " pear " );? //
            }

            ?

            下面我們仔細分析整個機制的幾個細節。
            先讓我們來看看pair的樣子。

            template < class ?T1,? class ?T2 > struct ?std::pair{? // 這里用struct來定義
            ????typedef?T1?first_type;
            ????typedef?T2?second_type;

            ????T1?first;
            ????T2?second;

            ????pair():?first(T1()),?second(T2()){}
            ????pair(
            const ?T1 & ?x,? const ?T2 & ?y):?first(x),?second(y){}
            ????template
            < class ?U,? class ?v >
            ????????pair(
            const ?pair < U,?V >& ?p):?first(p.first),?second(p.second){}
            ????
            //
            };

            注意pair的兩個數據成員first, second都是public的,所以Iseq繼承pair之后可以直接訪問。

            考察find()函數的重載版本
            find(Iseq<In> r, const T& v)
            注意“Iseq<In> r”使用值傳遞,而不用引用傳遞(Iseq<In>& r)。
            這是因為iiseq協助函數返回一個臨時對象,所以在find中,不能用引用傳遞。
            template<class C>Iseq<typename C::iterator> iiseq(C& c) //C為容器
            {
            ?return Iseq<typename C::iterator>(c.begin(), c.end());
            }
            大家可能會考慮到效率問題,覺得值傳遞可能不妥。其實不然,我們可以發現,Iseq里面的數據成員是兩個Iterator,一般來說不是很大(有時,就是兩個指針),在效率上不會產生很大的影響。

            還有這里代碼中出現typename,(如return Iseq<typename C::iterator>(c.begin(), c.end());) 可能對初學者來說有些生疏。為什么不直接寫: Iseq<C::iterator>(c.begin(), c.end())。這是由于編譯器不能直接認出C::iterator是一種類型,所以我們加上修飾符號typename告訴編譯器C::iterator使用一種類型。


            ?

            posted on 2006-06-02 22:25 TH 閱讀(211) 評論(0)  編輯 收藏 引用 所屬分類: STL和標準函數庫
            色偷偷88888欧美精品久久久| 久久人人爽人人爽人人片AV东京热| 少妇人妻88久久中文字幕| 久久久久99精品成人片欧美| 久久亚洲精品中文字幕三区| 欧美日韩精品久久久久| 亚洲精品无码久久久久去q | 性色欲网站人妻丰满中文久久不卡| 亚洲国产另类久久久精品小说| 精品国产乱码久久久久久1区2区| 日韩人妻无码精品久久久不卡| 国产V综合V亚洲欧美久久| 久久久久久狠狠丁香| 久久久久久伊人高潮影院| 色偷偷偷久久伊人大杳蕉| 国产精自产拍久久久久久蜜| 久久亚洲欧美国产精品| 精品久久久久国产免费| av色综合久久天堂av色综合在| 99久久免费国产精精品| 久久久久久精品免费免费自慰| 99久久亚洲综合精品网站| 久久久久99精品成人片试看| 久久天天躁狠狠躁夜夜2020一| 国产精品日韩欧美久久综合| 狠狠干狠狠久久| 99久久人妻无码精品系列蜜桃| 狠狠色丁香久久婷婷综合_中 | 要久久爱在线免费观看| 中文字幕亚洲综合久久| 麻豆精品久久精品色综合| 久久精品欧美日韩精品| 亚洲AV日韩精品久久久久久久| 久久天天躁狠狠躁夜夜avapp| 欧美成人免费观看久久| 天天影视色香欲综合久久| 久久亚洲欧洲国产综合| 亚洲欧美久久久久9999| 久久这里的只有是精品23| 久久无码中文字幕东京热| 久久SE精品一区二区|