欧美在线专区-欧美在线伊人-欧美在线一区二区三区欧美-欧美在线一区二区三区-pornodoxxx中国妞-pornodoldoo欧美另类

C++仿函數你知道怎么做嗎?

[導讀]在我們日常編碼中會發現有些功能代碼,函數會不斷的知道在不同的成員函數中用到,但是函數又不好將這些代碼獨立成一個成員函數。解決辦法之一就是知道寫一個公共的函數,不過函數用到的函數一些變量,就可能會成為全局變量。知道再說為了復用這么一段代碼,函數就要單立出一個函數,知道也不是函數很好維護。此時就可以用到仿函數了。知道

【導讀】:在我們日常編碼中會發現有些功能代碼,函數會不斷的知道在不同的成員函數中用到,但是函數又不好將這些代碼獨立成一個成員函數。解決辦法之一就是知道寫一個公共的函數,不過函數用到的函數一些變量,就可能會成為全局變量。再說為了復用這么一段代碼,就要單立出一個函數,也不是很好維護。此時就可以用到仿函數了。

C++仿函數你知道怎么做嗎?


以下是正文



引入仿函數(functor)原因


先考慮一個簡單的例子:假設有一個vector,你的任務是統計長度小于5的string的個數,如果使用count_if函數的話,你的代碼可能長成這樣:

    bool LengthIsLessThanFive(const string& str){ ????return?str.length()?< 5;????}int res=count_if(vec.begin(), vec.end(), LengthIsLessThanFive);

    其中count_if函數的第三個參數是一個函數指針,返回一個bool類型的值。一般的,如果需要將特定的閾值長度也傳入的話,我們可能將函數寫成這樣:

      bool LenthIsLessThan(const string& str, int len) { ????return?str.length()?< len;}

      這個函數看起來比前面一個版本更具有一般性,但是他不能滿足count_if函數的參數要求:count_if要求的是unary function(僅帶有一個參數)作為它的最后一個參數。所以問題來了,怎么樣找到以上兩個函數的一個折中的解決方案呢?


      這個問題其實可以歸結于一個data flow的問題,要設計這樣一個函數,使其能夠access這個特定的length值,回顧我們已有的知識,有三種解決方案可以考慮:


      (1)函數的局部變量:

      局部變量不能在函數調用中傳遞,而且caller無法訪問。


      (2)函數的參數:

      這種方法我們已經討論過了,多個參數不適用于count_if函數。


      (3)全局變量:

      我們可以將長度閾值設置成一個全局變量,代碼可能像這樣:

        int maxLength;bool LengthIsLessThan(const string& str) { return str.length() < maxLength;}int res=count_if(vec.begiin(), vec.end(), LengthIsLessThan);

        這段代碼看似很不錯,實則不符合規范,更重要的是,它不優雅。原因有以下幾點要考慮:


        (1)容易出錯:

        為什么這么說呢,我們必須先初始化maxLength的值,才能繼續接下來的工作,如果我們忘了,則可能無法得到正確答案。此外,變量maxLength和函數LengthIsLessThan之間是沒有必然聯系的,編譯器無法確定在調用該函數前是否將變量初始化,給碼農平添負擔。


        (2)沒有可擴展性:

        如果我們每遇到一個類似的問題就新建一個全局變量,尤其是多人合作寫代碼時,很容易引起命名空間污染(namespace polution)的問題;當范圍域內有多個變量時,我們用到的可能不是我們想要的那個。


        (3)全局變量的問題:

        每當新建一個全局變量,即使是為了coding的便利,我們也要知道我們應該盡可能的少使用全局變量,因為它的cost很高;而且可能暗示你這里有一些待解決的優化方案。


        仿函數(functor)介紹


        說了這么多,還是要回到我們原始的那個問題,有什么解決方案呢?答案當然就是這篇blog的正題部分:仿函數。


        我們的初衷是想設計一個unary function,使其能做binary function的工作,這看起來并不容易,但是仿函數能解決這個問題。


        先來看仿函數的通俗定義:仿函數(functor)又稱為函數對象(function object)是一個能行使函數功能的類。仿函數的語法幾乎和我們普通的函數調用一樣,不過作為仿函數的類,都必須重載operator()運算符,舉個例子:

          class Func{ public:void operator() (const string& str) const { cout<????????}};Func myFunc;myFunc("helloworld!");

          >>>helloworld!


          仿函數其實是上述解決方案中的第四種方案:成員變量。成員函數可以很自然的訪問成員變量:

            class StringAppend{ public:explicit StringAppend(const string& str) : ss(str){ }
            void operator() (const string& str) const{ cout<}
            private:const string ss; };
            StringAppend myFunc("is world");myFunc("hello");

            >>>hellois world


            我相信這個例子能讓你體會到一點點仿函數的作用了;它既能像普通函數一樣傳入給定數量的參數,還能存儲或者處理更多我們需要的有用信息。


            讓我們回到count_if的問題中去,是不是覺得問題變得豁然開朗了?

              class ShorterThan { public:explicit ShorterThan(int maxLength) : length(maxLength) { }bool operator() (const string& str) const { return str.length() < length;}private:const int length;};//直接調用即可count_if(myVector.begin(), myVector.end(), ShorterThan(length));

              這里需要注意的是,不要糾結于語法問題:ShorterThan(length)似乎并沒有調用operator()函數?其實它調用了,創建了一個臨時對象。你也可以自己加一些輸出語句看一看。


              這篇博文就先記到這里了,仿函數也在STL中大量涉及到,不徹底弄懂仿函數的問題看到STL源碼就會一頭包。后續可能再分享一些關于functor的資料和個人學習心得。


              來源:dnbc66

              鏈接:www.cnblogs.com/decade-dnbc66/p/5347088.html

              免責聲明:本文內容由21ic獲得授權后發布,版權歸原作者所有,本平臺僅提供信息存儲服務。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯系我們,謝謝!

              Popular articles

              主站蜘蛛池模板: 美女把尿口扒开让男人桶| 欧美日韩一区二区成人午夜电影| 免费看的黄色大片| 欧美精品寂寞影院请用uc| 卡一卡二卡三精品| 国产精品久久久久久久| 男人和男人一起差差| 国产在线高清视频无码| 天天夜天干天天爽| 九九精品99久久久香蕉| 亚洲噜噜噜噜噜影院在线播放| 午夜电影院理论片8888琪琪| 小向美奈子中出播放| 亚洲冬月枫中文字幕在线看| 日韩一级黄色片| 天天爱夜夜做| 蜜汁肉桃h全篇| 久操视频免费观看| 欧美电影《轻佻寡妇》| 亚洲一区二区影院| 小镇姑娘hd电影在线观看| 再深点灬舒服了灬太大| 法国性经典xxxxhd| 美女羞羞视频免费网站| 国产成品精品午夜视频| 一个人看的www日本高清视频| 免费毛片a线观看| 欧美特黄a级高清免费大片| 日本在线观看一级高清片| 午夜精品久久久久久| 两根硕大一起挤进小h| 99xxoo视频在线永久免费观看| 毛片免费观看网址| 天天干天天射天天操| 穿长筒袜的有夫之妇hd中文 | 四虎成人永久地址| 四虎4hutv永久在线影院| 99re热这里有精品首页视频| 樱花草在线社区www韩国| 欧美kkk4444在线观看| 一级毛片无毒不卡直接观看|