• <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 閱讀(207) 評論(0)  編輯 收藏 引用 所屬分類: STL和標準函數庫
            精品欧美一区二区三区久久久| 久久久久久精品无码人妻| 香蕉久久av一区二区三区| 久久综合狠狠综合久久| 色综合久久中文色婷婷| 久久久这里有精品中文字幕| 久久无码AV中文出轨人妻| 99国产精品久久| 久久香综合精品久久伊人| 国产精品狼人久久久久影院| 7777久久久国产精品消防器材| 久久91综合国产91久久精品| 亚洲人成电影网站久久| 国产精品99久久久久久猫咪| 久久精品国产亚洲AV无码麻豆| 亚洲欧美日韩久久精品| 91超碰碰碰碰久久久久久综合| 日本WV一本一道久久香蕉| 国产成人精品综合久久久| 国产成人无码久久久精品一| 亚洲婷婷国产精品电影人久久| 日韩精品国产自在久久现线拍| 日产精品久久久一区二区| 久久毛片一区二区| 香蕉99久久国产综合精品宅男自 | 亚洲欧美精品一区久久中文字幕| 狠狠色丁香久久婷婷综合| 久久久久人妻一区精品| 四虎国产精品免费久久5151| 国产V综合V亚洲欧美久久| 亚洲精品国产美女久久久| 人人妻久久人人澡人人爽人人精品| 精品久久久无码中文字幕天天 | 亚洲国产精品久久久天堂| 久久影院亚洲一区| 久久精品无码av| 色偷偷88欧美精品久久久| 欧美成a人片免费看久久| 亚洲国产小视频精品久久久三级 | 久久九九免费高清视频| 久久午夜无码鲁丝片午夜精品|