天天看點

C++函數對象count_if用法(轉)

     标準庫裡的count_if可以統計容器中滿足特定條件的元素的個數。例如要統計一個整數vector——ivec中正數的個數,可以先寫一個傳回類型為bool,含有一個int參數的條件函數:

C++函數對象count_if用法(轉)
C++函數對象count_if用法(轉)

bool pred(int val)...{

C++函數對象count_if用法(轉)

    return val>0;

C++函數對象count_if用法(轉)

}

     之後可以用count_if(ivec.begin(),ivec.end(),pred)計算出正整數的個數。但這個方法有一個明顯的缺陷:如果要統計大于10的個數、大于100的個數……就要寫很多個類似的函數,能不能進一步抽象?如果能像這樣調用count_if:count_if(ivec.begin(),ivec.end,pred(n)),就能統計出容器裡大于n的個數,那該多好呀。函數對象提供了這樣一種機制。

     簡單地說,函數對象就是一個重載了()運算符的對象,它可以像一個函數一樣使用。例如這個Add類:

C++函數對象count_if用法(轉)
C++函數對象count_if用法(轉)

class Add...{

C++函數對象count_if用法(轉)

    public:

C++函數對象count_if用法(轉)
C++函數對象count_if用法(轉)

        int operator()(int v1, int v2)...{

C++函數對象count_if用法(轉)

            return v1+v2;

C++函數對象count_if用法(轉)

         }

C++函數對象count_if用法(轉)

};     它能夠進行加法運算。例如: 

C++函數對象count_if用法(轉)

int a1=3,a2=1;

C++函數對象count_if用法(轉)

Add add;

C++函數對象count_if用法(轉)

cout<<add(a1,a2)<<endl;

     結果将是4。那麼這種機制怎樣用在剛才的問題上呢?因為count_if的第三個參數是一個接受一個參數的函數,是以可以通過一個構造函數将這個參數傳到對象裡,由count_if自動調用這個函數對象:

C++函數對象count_if用法(轉)
C++函數對象count_if用法(轉)

class Pred...{

C++函數對象count_if用法(轉)

    private:

C++函數對象count_if用法(轉)

        int _val;

C++函數對象count_if用法(轉)

    public:

C++函數對象count_if用法(轉)
C++函數對象count_if用法(轉)

         Pred(int val):_val(val)...{}

C++函數對象count_if用法(轉)
C++函數對象count_if用法(轉)

        bool operator()(int val)...{

C++函數對象count_if用法(轉)

            return val>_val;

C++函數對象count_if用法(轉)

         }

C++函數對象count_if用法(轉)

};

     于是,要統計大于100的個數,就可以寫成:count_if(ivec.begin(),ivec.end(),Pred(100))。Pred(100)構造一個函數對象,count_if把這個對象依次應用到容器中的每一個元素,隻要它傳回一個真值,計數器就加1。

     如果再利用模闆技術,則可以應用到各種類型的容器上:

C++函數對象count_if用法(轉)

template<typename T>

C++函數對象count_if用法(轉)
C++函數對象count_if用法(轉)

class Pred...{

C++函數對象count_if用法(轉)

    private:

C++函數對象count_if用法(轉)

         T _val;

C++函數對象count_if用法(轉)

    public:

C++函數對象count_if用法(轉)
C++函數對象count_if用法(轉)

         Pred(T val):_val(val)...{}

C++函數對象count_if用法(轉)
C++函數對象count_if用法(轉)

        bool operator()(T val)...{

C++函數對象count_if用法(轉)

            return val>_val;

C++函數對象count_if用法(轉)

         }

C++函數對象count_if用法(轉)

};

     這樣,剛才的統計語句就應該寫成:count_if(ivec.begin(),ivec.end(),Pred<int>(100))。如果容器是double類型的,隻需把尖括号裡的int換成double即可。

轉載于:https://www.cnblogs.com/PegasusWang/archive/2013/04/20/3032891.html