• <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>
            aurain
            技術(shù)文摘
            posts - 137,  comments - 268,  trackbacks - 0

                   STL不但使我們能夠更輕松、更快捷地編寫復(fù)雜的代碼,而且使編寫的代碼既標(biāo)準(zhǔn)又高度優(yōu)化。

            std::vector<std::string> names;

            // ...

            std::sort(names.begin(), names.end());

                   STL另一個(gè)優(yōu)雅之處在于高度可配置。在以上的代碼中,使用string的小于(<)操作符對vector中的string元素進(jìn)行排序,但在其它場合,未必總有一個(gè)小于操作符可供使用,而且有時(shí)并不希望以升序方式進(jìn)行排序。

                   class State

            {

            public:

               // ...

               int population() const;

               float aveTempF() const;

               // ...

            };

            State類用于表示聯(lián)邦的一個(gè)州,它沒有小于操作符,而且也不打算為它實(shí)現(xiàn)一個(gè),因?yàn)?#8220;一個(gè)州小于另一個(gè)州”說不清是什么意思。幸運(yùn)的是,對于這樣的情形來說,STL一般允許我們指定一個(gè)替代的類似小于操作符(less-than-like)的操作。這樣的操作被稱為“比較器”,因?yàn)樗糜诒容^兩個(gè)值:

                   inline bool popLess(const State& a, const State& b)

            {

                 return a.population() < b.population();

            }

            擁有針對State的比較器之后,就可以用它進(jìn)行排序了:

            State aUnion[50];

            // ...

            std::sort(aUnion, aUnion + 50, popLess); // 按人口數(shù)進(jìn)行排序

            這里我們傳遞一個(gè)指向popLess函數(shù)的指針作為比較器(函數(shù)名字會(huì)退化成一個(gè)指針)。因?yàn)?/span>popLess作為函數(shù)指針進(jìn)行傳遞,所以它在sort內(nèi)無法被內(nèi)聯(lián)。如果希望得到快速的排序操作,這種做法只能讓人感到遺憾了。

                   如果使用函數(shù)對象作為比較器,情況就會(huì)好很多:

                   struct PopLess : public std::binary_function<State, State, bool>

            {

               bool operator () (const State& a, const State& b) const

               {

                  return a.population() < b.population();

               }

            };

                   PopLess類型是一個(gè)典型的、有著正確構(gòu)造的STL函數(shù)對象的例子。

            首先,它是一個(gè)函數(shù)對象。它重載了函數(shù)調(diào)用操作符,因此可以以普通函數(shù)調(diào)用的語法調(diào)用。這一點(diǎn)很重要,因?yàn)橹T如sort這樣的STL泛型算法是以這種方式編寫的:函數(shù)指針和函數(shù)對象都可以用來實(shí)例化它們,只要此二者可以采用典型的函數(shù)調(diào)用語法進(jìn)行調(diào)用即可。一個(gè)具有重載的operator()的函數(shù)對象完全可以滿足這個(gè)語法要求。

                   其次,它派生于標(biāo)準(zhǔn)的binary_function基類。此項(xiàng)機(jī)制允許其它部分的STL實(shí)現(xiàn)詢問函數(shù)對象編譯器問題。在這個(gè)例子中,從binary_function派生下來的PopLess類型允許我們找出函數(shù)對象的參數(shù)和返回值類型。不過在這里我們并沒有利用這種能力,但是可以打賭肯定有人需要這樣的能力,而且希望我們的PopLess類型可以為其他人所用。

                   第三,這個(gè)函數(shù)對象沒有數(shù)據(jù)成員、沒有虛函數(shù)、沒有顯示聲明的構(gòu)造函數(shù)和析構(gòu)函數(shù),且對operator()的實(shí)現(xiàn)是內(nèi)聯(lián)的。用作STL比較器的函數(shù)對象一般都很小巧。簡單且快速。當(dāng)然可以設(shè)計(jì)一個(gè)具有重型實(shí)現(xiàn)的STL函數(shù)對象,但這種做法通常不是明智之舉。當(dāng)與STL協(xié)同使用時(shí),在函數(shù)對象中避免(或盡量少)使用數(shù)據(jù)成員的另一個(gè)原因在于,STL實(shí)現(xiàn)可能為會(huì)一個(gè)函數(shù)對象產(chǎn)生若干份復(fù)制,而且假定所有這些復(fù)制都是一致的。為了確保一個(gè)對象的所有復(fù)制一致,最簡單的方式就是不要讓對象帶有任何數(shù)據(jù)成員。

                   現(xiàn)在我們就可以使用該函數(shù)對象對這個(gè)aUnion進(jìn)行排序:

                   std::sort(aUnion, aUnion + 50, PopLess());   // 按人口數(shù)進(jìn)行排序

                   請注意在這個(gè)sort調(diào)用中跟在PopLess后面的圓括號(hào)。PopLess是一個(gè)類型,但是我們必須傳入一個(gè)該類型的對象作為函數(shù)的參數(shù)。通過在PopLess類型名字后面附加一對圓括號(hào),就創(chuàng)建了一個(gè)沒名字的臨時(shí)PopLess對象,此對象僅存活于函數(shù)調(diào)用期間(這個(gè)沒名字的對象即總所周知的“匿名臨時(shí)對象”)。也可以聲明并傳入一個(gè)具名對象:

                   PopLess comp;

            std::sort(aUnion, aUnion + 50, comp); // 按人口數(shù)進(jìn)行排序

            然而,傳入一個(gè)匿名臨時(shí)對象更簡單、更符合習(xí)慣,而且擊鍵次數(shù)更少。

            使用函數(shù)對象作為比較器還有一個(gè)額外的好處,就是比較操作將被內(nèi)聯(lián)處理,而使用函數(shù)指針則不允許內(nèi)聯(lián)。原因在于,當(dāng)一個(gè)sort函數(shù)模板實(shí)例化時(shí),編譯器知道比較器的類型是PopLess,從而使它知道PopLess:operator()將被調(diào)用,接著使它可以內(nèi)聯(lián)該函數(shù)。

            STL中,函數(shù)對象另一個(gè)常見的用途是用作判斷式。判斷式是一個(gè)詢問關(guān)于單個(gè)對象的真/假問題的操作(可以將比較器視作一種二元判斷式)。

            struct IsWarm : public std::unary_function<State, bool>

            {

               bool operator () (const State& a) const

               {

                  return a.aveTempF() > 60;

               }

            };

            STL判斷式的設(shè)計(jì)知道方針與STL比較器的一致,唯一的例外在于,前者是一元函數(shù),而非二元函數(shù)。從我們前面排過序的State結(jié)果開始,采用一個(gè)適當(dāng)?shù)呐袛嗍剑梢宰屛覀兒苋菀拙湍苷业揭粋€(gè)氣候溫暖且人數(shù)較少的州:

            State* warmandsparse = find_if(aUnion, aUnion + 50, IsWarm());

             

            posted on 2011-06-29 08:46 閱讀(2889) 評(píng)論(1)  編輯 收藏 引用 所屬分類: c/c++基礎(chǔ)知識(shí)

            FeedBack:
            # re: STL函數(shù)對象
            2011-06-29 17:27 | 陳梓瀚(vczh)
            如今可以簡寫為[](onst State& a){return a.aveTempF()>60;}了  回復(fù)  更多評(píng)論
              

            <2009年4月>
            2930311234
            567891011
            12131415161718
            19202122232425
            262728293012
            3456789

            常用鏈接

            留言簿(17)

            隨筆分類(138)

            隨筆檔案(137)

            網(wǎng)絡(luò)開發(fā)

            最新隨筆

            搜索

            •  

            積分與排名

            • 積分 - 497507
            • 排名 - 36

            最新隨筆

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            狠狠色综合久久久久尤物| 国产aⅴ激情无码久久| 久久精品国产亚洲AV高清热| 色婷婷狠狠久久综合五月| 亚洲国产精品狼友中文久久久| 久久久久久午夜成人影院 | 午夜不卡久久精品无码免费| 亚洲精品无码专区久久同性男| 久久国产视频网| 国产亚洲精午夜久久久久久| 久久国产视屏| 午夜福利91久久福利| 久久中文字幕视频、最近更新| 久久久久久久久久久免费精品| 久久影视综合亚洲| 亚洲精品久久久www| 国产免费久久精品99re丫y| 久久99国产精品久久99小说| 波多野结衣久久精品| 人妻无码精品久久亚瑟影视 | 精品久久久久久久国产潘金莲 | 久久久久亚洲av成人网人人软件| 久久人人青草97香蕉| 亚洲精品乱码久久久久久| 77777亚洲午夜久久多喷| 91精品国产高清久久久久久91| 成人国内精品久久久久影院VR| 久久婷婷五月综合成人D啪| 久久伊人精品一区二区三区| 久久精品国产亚洲av高清漫画| 9191精品国产免费久久| 亚洲午夜精品久久久久久浪潮| 亚洲综合伊人久久综合| 青青草原1769久久免费播放| 久久久久无码精品| 亚洲香蕉网久久综合影视| 久久九九有精品国产23百花影院| 三级片免费观看久久| 国内精品久久久久久久97牛牛| 久久www免费人成看国产片| 亚洲AV无码久久精品狠狠爱浪潮|