1. 程式人生 > >C++ STL 函式物件

C++ STL 函式物件

函式物件:

1.函式名

2.指向函式的指標

3.過載了()的類

函式名就是普通的函式,指向函式的指標會造成的一些問題是gdb、kdb的時候,呼叫棧會出現問題,因為這些除錯工具跟蹤的是函式名,用地址呼叫的時候符號表裡面無法反應。使用過載了()的類物件的一個特點是可以使用額外的變數,例如構造物件的時候傳入的私有成員資料。

函式符:

1.生成器:沒有引數的函式符

2.一元函式:一個引數

3.二元引數:兩個引數

謂詞:返回bool值的一元函式

二元謂詞:返回bool值的二元函式

使用過載了()的類的物件的一個好處是,需要調整值的時候,只要新建立一個物件就行而不用重新修改函式,例如,對於list的一個成員函式remove_if,引數是一個一元謂詞,當返回值為true的時候,將節點刪除,比如n > 100是條件,那麼使用如下:

bool toobig(int n)
{
    if (n > 100)
        return true;
    return false;
}

list<int> tmp;
tmp.remove_if(toobig);

下次若需要判斷n > 200,就需要增加一個函式,若有頻繁使用不同取捨值的場景,那麼使用函式物件較好,每次建立新的物件就行了,如下:

template <typename T>
class TooBig
{
private:
    T cutoff;
public:
    TooBig(const T & t) : cutoff(t){}
    bool operator()(const T & t){return t > cutoff;}
};

list<int>tmp;
tmp.remove_if(TooBig<int>(10));

STL預定義函式符:標頭檔案functional,是一些模板類物件,定義這些是為了防止對每種型別都定義一個同樣功能的函式,比如double的加法和int的加法,可以直接用plus<>模板類,使用如下:

#include <functional>
plus<double>add;
double tmp = add(1.1, 2.2);    //plus<double>.operator()

所有內建算數運算子、關係運算符、邏輯運算子都有STL預定義的函式符

函式介面卡:bind1st:用來製作介面卡,將一個二元函式適配成一個一元函式,bind2nd用來替換的是第二個引數,如下:

void func2()
{
    double arr1[] = {28, 29, 30, 35, 38, 59};
    double arr2[] = {63, 65, 69, 75, 80, 99};
    vector<double>gr8(arr1, arr1 + 6);
    vector<double>m8(arr2, arr2 + 6);

    /* 5個引數的transform,使用二元函式 */
    vector<double>sum(6);
    transform(gr8.begin(), gr8.end(), m8.begin(), sum.begin(), plus<double>());
    for_each(sum.begin(), sum.end(), show);
    cout << endl;

    /* 使用bind1st提供介面卡,將二元函式轉換為一元函式 */
    vector<double>prod(6);
    transform(gr8.begin(), gr8.end(), prod.begin(), bind1st(multiplies<double>(), 2.5));
    for_each(prod.begin(), prod.end(), show);
    cout << endl;
}

C++11提供了lambda表示式,和python差不多