• <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++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              4 隨筆 :: 4 文章 :: 9 評論 :: 0 Trackbacks

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

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

            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給出一個解決問題的途徑。其關(guān)鍵就是用整個容器代替x.begin, x.end()的輸入。
            這樣,我們要封裝兩個東西,1、find()函數(shù)。 2、begin(),end()

            利用重載,封裝find函數(shù)。

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

            ?

            利用對偶,封裝迭代器。
            首先,我們構(gòu)造一個Iseq以保證迭代器是統(tǒng)一序列成對輸入的。

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

            ?

            接著構(gòu)造一個協(xié)助函數(shù),直接傳遞容器。

            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 " );? //
            }

            ?

            下面我們仔細分析整個機制的幾個細節(jié)。
            先讓我們來看看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的兩個數(shù)據(jù)成員first, second都是public的,所以Iseq繼承pair之后可以直接訪問。

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

            還有這里代碼中出現(xiàn)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 閱讀(207) 評論(0)  編輯 收藏 引用 所屬分類: STL和標準函數(shù)庫
            97精品依人久久久大香线蕉97| 久久亚洲高清观看| 无码精品久久一区二区三区 | 精品久久综合1区2区3区激情| 久久99免费视频| 亚洲成av人片不卡无码久久 | 久久国产乱子伦精品免费强| 久久久99精品成人片中文字幕| 亚洲AV伊人久久青青草原| 日韩精品久久久肉伦网站| 国内精品久久久久久中文字幕| 狠狠色丁香久久婷婷综合| 久久久久国产精品| 亚洲成色WWW久久网站| 久久se精品一区二区影院| 亚洲午夜久久久久久久久久| 精品久久久久久久久久中文字幕 | 精品久久久久香蕉网| 色播久久人人爽人人爽人人片aV | 欧美无乱码久久久免费午夜一区二区三区中文字幕 | 国产精品青草久久久久婷婷| 亚洲国产天堂久久综合| 久久综合丁香激情久久| 亚洲中文字幕无码久久精品1| 国产巨作麻豆欧美亚洲综合久久| 国产A级毛片久久久精品毛片| 久久久久无码精品| yellow中文字幕久久网| www.久久热| 久久se精品一区二区| 91精品国产9l久久久久| 久久99精品久久久久久hb无码| 国内精品伊人久久久久777| 久久无码一区二区三区少妇| 99久久成人18免费网站| 91精品国产综合久久四虎久久无码一级 | 久久久久久人妻无码| 亚洲午夜无码久久久久| 人妻无码αv中文字幕久久| 国产成人久久精品一区二区三区 | 国产精品久久网|