• <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ù)庫
            久久乐国产综合亚洲精品| 久久精品国产免费一区| 一本色综合网久久| 精品久久久噜噜噜久久久| 色综合久久久久网| 奇米影视7777久久精品人人爽| 无码人妻精品一区二区三区久久| 久久99国产精一区二区三区| 精品久久久一二三区| 久久99国产一区二区三区| 伊人久久精品无码av一区| 久久无码国产| 99久久99久久精品国产| 日韩精品久久无码中文字幕| 久久中文精品无码中文字幕| 久久99精品久久久久久| 久久人人爽人人人人片av| 久久久久久久国产免费看| 四虎国产精品免费久久久| 少妇精品久久久一区二区三区| 久久性生大片免费观看性| 亚洲精品高清久久| 久久久久久九九99精品| 久久亚洲AV无码精品色午夜| 亚洲第一永久AV网站久久精品男人的天堂AV | 久久精品中文无码资源站| 无码8090精品久久一区| 久久99精品久久久久久水蜜桃| 久久国产免费观看精品3| 久久亚洲美女精品国产精品| 久久精品卫校国产小美女| 亚洲国产成人久久综合区| 亚洲欧洲久久av| 久久无码专区国产精品发布| 一级a性色生活片久久无少妇一级婬片免费放 | 女人香蕉久久**毛片精品| 麻豆亚洲AV永久无码精品久久| 99久久夜色精品国产网站| 亚洲国产精品一区二区久久hs| 久久天天躁狠狠躁夜夜网站| 777米奇久久最新地址|