久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

<STL源碼剖析>閱讀筆記之 仿函數(shù)和適配器

 Fredanf 2012-12-09

<STL源碼剖析>閱讀筆記之 仿函數(shù)和適配器

  仿函數(shù)(函數(shù)對象)和適配器可以說是STL中默默無聞的貢獻(xiàn)者,,它們沒有容器、算法和迭代器那么有名

但是其貢獻(xiàn)卻很大,。這里總結(jié)的主要是書中第7,、8章的內(nèi)容,。

一 仿函數(shù)

  仿函數(shù)又稱函數(shù)對象,,從名字上可以得出,它本質(zhì)上是 一種具有函數(shù)特質(zhì)的對象,, 也即可以像使用函

數(shù)一樣使用該對象,。怎么樣做?重載operator()運(yùn)算符即可,,有了這個(gè)運(yùn)算符,,我們就可以在仿函數(shù)對象后

面加上一對小括號,以此調(diào)用仿函數(shù)所定義的operator(),。STL仿函數(shù)可以分為一元和二元,,或者算術(shù)運(yùn)

算、關(guān)系運(yùn)算和邏輯運(yùn)算,。

  為什么要有仿函數(shù),?在算法的設(shè)計(jì)過程中,我們會(huì)發(fā)現(xiàn)其本質(zhì)往往是不變的(例如排序算法的思想),,變

化的除了數(shù)據(jù)之外還有操作(例如排序中不一定是比較大小,,也可以是兩兩之間滿足某種關(guān)系),,仿函數(shù)就

是為了這種情況產(chǎn)生的,它替代原來需要函數(shù)指針的地方,,把這種操作或者策略傳給算法,,使得算法抽象性

更高,也就更通用,。

  為什么不用函數(shù)指針,?很簡單的解釋是抽象性不夠,更進(jìn)一步說是它無法配接,,也就是可以將操作配接在

一起變換為更復(fù)雜的操作(例如compose和bind1st等等方法),,仿函數(shù)則可以輕松實(shí)現(xiàn)這些配接,使得其功

能異常強(qiáng)大,。

  仿函數(shù)在實(shí)現(xiàn)上是一個(gè)結(jié)構(gòu)體,,并且如上所述重載了operator()運(yùn)算符,所有的仿函數(shù)如果是一元的都繼

承自unary_function,,二元?jiǎng)t繼承自binary_function,因?yàn)槔^承自這兩個(gè)函數(shù)的仿函數(shù)均定義了相應(yīng)型別供

配接時(shí)使用,,也就具有了配接能力。

template <class Arg, class Result>
struct unary_function {
    typedef Arg argument_type;
    typedef Result result_type;
};

template <class Arg1, class Arg2, class Result>
struct binary_function {
    typedef Arg1 first_argument_type;
    typedef Arg2 second_argument_type;
    typedef Result result_type;
}; 

  從以上代碼可以看到,,這兩個(gè)類僅僅只是定義了相應(yīng)型別,,至于STL內(nèi)置的仿函數(shù)則僅僅是重載了()運(yùn)

算,很簡單:

//加法是二元運(yùn)算符所以繼承自binary_function
template <class T>
struct plus : public binary_function<T, T, T> {
    T operator()(const T& x, const T& y) const { return x + y; }
};

//非是一元邏輯運(yùn)算符,,所以繼承自unary_function
template <class T>
struct logical_not : public unary_function<T, bool> {
    bool operator()(const T& x) const { return !x; }
};

二 適配器

  適配器也是一種常用的設(shè)計(jì)模式: 將一個(gè)class的接口轉(zhuǎn)換為另一個(gè)class的接口,,使得原本因接口不兼容

而不能合作的classes可以一起運(yùn)作。一個(gè)通俗的例子是我們筆記本的電源,,一般都會(huì)有一個(gè)適配器把220v

的電壓降到適合筆記本工作的電壓范圍,,這樣筆記本就可以工作在我們常用的電壓環(huán)境了,這就擴(kuò)大了筆記

本的使用場景,,在軟件開發(fā)過程中也是一樣的道理,。

  STL提供三種適配器:改變?nèi)萜鹘涌诘娜萜鬟m配器、改變迭代器接口的迭代器適配器以及改變仿函數(shù)接口

的仿函數(shù)適配器,。前兩者都較為簡單,,而最后一種則是靈活性最大的,有了它我們可以構(gòu)造非常復(fù)雜的表達(dá)

式策略,。

  容器適配器常見的是stack和queue,,他們的底層存儲(chǔ)都是用deque完成的,再在deque上封裝一層接口以

滿足stack和queue的要求,。

  迭代器適配器大致有三種對應(yīng)不同的迭代器行為,,它們以某容器為參數(shù),直接對容器的迭代器進(jìn)行封

裝,,主要有back_insert_iterator,、front_insert_iterator,、insert_iterator以及reverse_iterator。

  從上面兩個(gè)適配器看,,其原理都是在其內(nèi)部有一個(gè)原來要適配的成員變量,,通過改變接口來實(shí)現(xiàn),那么仿

函數(shù)的適配器也不例外,。常用的是bind1st,bind2nd,not1,compose1,compose2等等,,這些適配器都是仿函數(shù)

同時(shí)以要適配的仿函數(shù)作為member object。

  仿函數(shù)適配器的實(shí)現(xiàn)主要包括兩塊,,自身的類以及方便使用的函數(shù),,以bind1st為例,它的作用是綁定二

元仿函數(shù)的第一個(gè)參數(shù)為某指定值,。首先是其定義:

//從它繼承自unary_function即可得知它也是仿函數(shù)
template <class Operation> 
class binder1st
  : public unary_function<typename Operation::second_argument_type,
                          typename Operation::result_type> {
protected:
  Operation op;  //以要適配的仿函數(shù)為成員變量
  typename Operation::first_argument_type value; //第一個(gè)參數(shù)
public:
  binder1st(const Operation& x,
            const typename Operation::first_argument_type& y)
      : op(x), value(y) {} //構(gòu)造函數(shù)里對兩個(gè)成員變量賦值
  typename Operation::result_type
  operator()(const typename Operation::second_argument_type& x) const {
    return op(value, x); //重載并接受第二個(gè)參數(shù),,以完成適配
  }
};

  仿函數(shù)適配器第二個(gè)部分是方便使用的函數(shù),以讓我們可以像普通函數(shù)一樣使用適配器,,并通過函數(shù)模板

的參數(shù)推導(dǎo)功能來創(chuàng)建適配器對象,。

template <class Operation, class T>
inline binder1st<Operation> bind1st(const Operation& op, const T& x) {
  typedef typename Operation::first_argument_type arg1_type;
  return binder1st<Operation>(op, arg1_type(x));//返回對象
}

  適配器很巧妙的構(gòu)造了這樣一種對象嵌套對象的結(jié)構(gòu)來使得我們可以構(gòu)造很復(fù)雜的語義,這也是函數(shù)指針

所不具備的,,當(dāng)然對于函數(shù)指針STL也提供了ptr_fun來將其變?yōu)楹瘮?shù)對象以獲得適配功能,,成員函數(shù)得使用

mem_fun,mem_fun_ref。

 

  總的來說,,通過對適配器和仿函數(shù)的學(xué)習(xí)我們看到了STL里面精妙的封裝,,以及對高度抽象的追求,也正

是這些高度抽象使得它更加通用性,。有了這些知識,,我們可以利用系統(tǒng)的迭代器構(gòu)造自己的迭代器,來擴(kuò)展

STL的功能,。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多