• <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 評(píng)論 :: 0 Trackbacks

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

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

            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 " );? // ?這個(gè)更加隱蔽。
            }

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

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

            template < class ?In,? class ?T > ?
            In?find(Iseq
            < In > ?r,? const ?T & ?v)?? // 通過重載機(jī)制,得到這個(gè)find的擴(kuò)充版本。
            {
            ????
            return ?find(r.first,?r.second,?v);? // 標(biāo)準(zhǔn)庫中的find
            };

            ?

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

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

            ?

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

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


            這樣,我們可以利用上面的機(jī)制,來避免所提出的錯(cuò)誤。

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

            ?

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

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

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


            ?

            posted on 2006-06-02 22:25 TH 閱讀(219) 評(píng)論(0)  編輯 收藏 引用 所屬分類: STL和標(biāo)準(zhǔn)函數(shù)庫
            无码国产69精品久久久久网站| 精品国产一区二区三区久久久狼| 国产成人精品久久综合 | 亚洲人成网亚洲欧洲无码久久| 新狼窝色AV性久久久久久| 国产三级久久久精品麻豆三级| 日本精品久久久中文字幕 | 人妻少妇久久中文字幕| 国产精品久久久久久久| 青青久久精品国产免费看| 国内精品久久人妻互换| 久久人搡人人玩人妻精品首页| 久久精品蜜芽亚洲国产AV| 欧洲国产伦久久久久久久| 久久最近最新中文字幕大全| 中文字幕精品久久久久人妻| 国产精品久久成人影院| 久久亚洲精品无码VA大香大香| 99热热久久这里只有精品68| 日韩人妻无码一区二区三区久久 | 久久婷婷五月综合国产尤物app| 色综合久久最新中文字幕| 漂亮人妻被黑人久久精品| 精品久久久久成人码免费动漫| 久久精品国产2020| 精品久久久噜噜噜久久久| 久久精品国产精品亚洲精品| 久久99精品久久久久久9蜜桃| 久久天堂电影网| 色综合久久无码五十路人妻| 国产精品久久久久久久app| 久久影院午夜理论片无码 | 97精品伊人久久久大香线蕉 | 伊人久久精品无码av一区| 亚洲国产成人精品久久久国产成人一区二区三区综 | 久久久久亚洲av成人网人人软件| 久久久久久av无码免费看大片| 亚洲国产精品婷婷久久| 亚洲成色999久久网站| 精品久久国产一区二区三区香蕉| 久久香蕉国产线看观看99|