C++STL之函數對象及謂詞

來源:互聯網
上載者:User
概述

函數對象是重載()運算子的類類型對象,即該類實現operator()()函數。STL將一組標準的函數對象定義為模板,,可以使用它們來建立一個函數對象,其中overload()運算子函數使用我們的物件類型。如:STL定義模板less<T>。如果將該模板執行個體化為less<myNumber>,我們就有了一個函數物件類型,實現operator()()來對myNumber類型的對象進行大小比較。

很多演算法使用函數對象來指定要進行的二元運算,或者指定謂詞來確定進行特定運算。謂詞是一個返回bool類型的值的函數,因為函數對象是一種類型的對象,實現operator()()成員函數並返回bool類型的值,所以函數對象也是謂詞。

謂詞有兩個版本,分別是需要兩個運算元的二元謂詞和需要一個運算元的一元謂詞。後文將會看到具體的應用。

應用

list中的remove_if()函數基於應用一元謂詞的結果來刪除列表中的元素,它返回一個bool型的值true或false。如果向一個元素應用謂詞的值為true,就會從列表中刪除該元素。通常我們會自己來定義自己的謂詞做我們想做的事情。這就需要為函數對象定義想採用的自己的類模板,STL定義用在這種上下文中的unary_function(T,R)基礎模板,定義如下:

template < class _Arg, class _Result > struct unary_function{    // base class for unary function    typedef _Arg argument_type;    typedef _Result result_type;};

用個具體的執行個體來展示用法。

//functionObject.h#pragma once#include <functional>template <class T> class is_negative: public std::unary_function<T, bool>{public:    result_type operator()(T& value)    {        return value < 0;    }};template < class T> class is_large: public std::unary_function<T,bool>{public:    result_type operator()(T &value)    {        //return value > 10;        if (value > 10)        {            return true;        }        else            return false;    }};template < class T> class is_odd : public std::unary_function<T,bool>{public:    result_type operator()(argument_type &value)    {        if ((value % 2) == 0)        {            return false;        }        else        {            return true;        }    }};
#include <iostream>#include <list>#include "function_object.h"#include <functional>using std::cin;using std::cout;using std::endl;using std::list;using std::greater;// Template function to list the contents of a listtemplate <class T>void listlist(list<T>& data){    for(list<T>::iterator iter = data.begin() ; iter != data.end() ; iter++)        cout << *iter << "  ";    cout << endl;}// Template function to read data from cin and store it in a listtemplate<class T>void loadlist(list<T>& data){    T value = T();    while(cin >> value , value != T())  //Read non-zero values        data.push_back(value);}int main(){    // Process integers    list<int> numbers;    cout << "Enter non-zero integers separated by spaces. Enter 0 to end."         << endl;    loadlist(numbers);    cout << "The list contains:" << endl;    listlist(numbers);    numbers.remove_if(is_odd<int>());    cout << "After applying the remove_if(is_odd()) function the list contains:"         << endl;    listlist(numbers);    numbers.remove_if(is_negative<int>());     cout << "After applying the remove_if() function the list contains:"         << endl;    listlist(numbers);    // Process floating-point values    list<double> values;    cout << endl         << "Enter non-zero values separated by spaces. Enter 0 to end."         << endl;    loadlist(values);    cout << "The list contains:" << endl;    listlist(values);        values.remove_if(is_negative<double>());            cout << "After applying the remove_if() function the list contains:" << endl;    listlist(values);    // Another list to use in merge    list<double> morevalues;    cout << endl         << "Enter non-zero values separated by spaces. Enter 0 to end."         << endl;    loadlist(morevalues);    cout << "The list contains:" << endl;    listlist(morevalues);    values.remove_if(is_negative<double>());            cout << "After applying the remove_if() function the list contains:" << endl;    listlist(morevalues);    // Merge the last two lists    values.sort(greater<double>());    morevalues.sort(greater<double>());    values.merge(morevalues, greater<double>());    listlist(values);    return 0;}

Functional標頭檔定義了一個可擴充的樣板集合,用來建立可用於演算法和容器的函數對象。常見的有:

全部用於建立二元謂詞

函數模板對象

說明

less<T>

表示T類型的<運算。如less<string>()定義一個比較string類型的函數對象。

less_equal<T>

同上,表示<=運算。

equal<T>

同上,表示=運算。

not_equal<T>

同上,表示!=運算。

greater_equal<T>

同上,表示>=運算。

greater<T>

同上,表示>運算。

not2<B>

它是B類型的二元謂詞的負值。

 

二元謂詞的建立基本同一元謂詞,但是用不同的模板而已。

template<class _Arg1,class _Arg2,class _Result>struct binary_function{    // base class for binary functions    typedef _Arg1 first_argument_type;    typedef _Arg2 second_argument_type;    typedef _Result result_type;};

例如:

class personValue:binary_function<Person, Person,bool>{    result_type operator()(const first_argument_type &p1,                           const second_argument_type &p2) const    {        return p1 > p2;    }};

實際運用:

主要應用於優先順序隊列,簡單介紹優先順序隊列。預設情況下,優先順序隊列適配器類使用的基礎容器為vector<T>。可以選擇不同的序列容器作為基礎,並選擇一個備用的函數對象確定元素的優先順序。如:

priority_queue<int,vector<int>,greater<int> > numbers;

這條語句基於vector<int>容器定義優先順序隊列,用greater<int>類型的函數對象插入元素。這個優先順序隊列中的元素將以降序排列,頂部為最小的元素。3 個模板形參是元素類型、要作為基礎的容器、要用來排列元素順序的謂詞類型。

如想想應用預設的謂詞(在這種情況下將是less<T>),則可以省略第三個參數。否則必須顯示地定義。

執行個體:

include <iostream>#include <vector>#include <queue>#include <functional>using std::cin;using std::cout;using std::endl;using std::vector;using std::priority_queue;using std::greater;using std::binary_function;class com:binary_function<int,int,bool>{public:    result_type operator()(first_argument_type &p1,         second_argument_type &p2) const    {        return p1>p2;    }};//class com//{//public://    bool operator()(int &p1,int &p2)const//    {//        return p1<p2;//    }//};int main(){    priority_queue<int,vector<int>,com > numbers;    int num;    cout<<"input numbers 0 to end"<<endl;    while(1)    {        cin>>num;        if (0 == num)        {            break;        }        numbers.push(num);    }    cout << endl << "There are " << numbers.size()        << " numbers in the queue."         << endl << endl;    while(!(numbers.empty()))    {        cout<<numbers.top()<<"  ";        numbers.pop();    }    return 0;}

我們將第三個參數的模板類型改成了我們自己的函數對象。可以通過繼承binary_function()或者自己定義(如注釋部分),效果是同樣的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.