1. 程式人生 > >謂詞、內建函式物件、函式物件介面卡

謂詞、內建函式物件、函式物件介面卡

一、謂詞概念

謂詞是指普通函式或過載的operator()返回值是bool型別的函式物件(仿函式)。如果operator接收一個引數,那麼叫做一元謂詞,如果接收兩個引數,那麼叫做二元謂詞,謂詞可作為一個判斷式。

二、內建函式物件

STL內建了一些函式物件,分為:算數類函式物件,關係運算類函式物件,邏輯運算類仿函式。這些仿函式所產生的物件,用法和一般函式完全相同,當然我們還可以產生無名的臨時物件來履行函式功能,使用內建函式物件,需要引入標頭檔案#include<functional>

6個算數類函式物件,除了negate是一元運算,其他都是二元運算。

6個關係運算類函式物件,每一種都是二元運算。

邏輯運算類仿函式,not為一元運算,其餘為二元運算。

案例(以plus為例):

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <functional>
using namespace std;

void test01()
{
    //使用內建函式物件宣告一個物件
    plus<int> myplus;
    cout << myplus(10, 20) << endl;//30
    //使用匿名臨時物件
    cout << plus<int
>()(5, 6) << endl;//11 } int main(void) { test01(); return 0; }

三、函式物件介面卡

函式物件介面卡是完成一些配接工作,這些配接包括繫結(bind),否定(negate),以及一對一般函式或成員函式的修飾,使其成為函式物件,重點掌握函式物件介面卡(紅色字型):

bind1st:將引數繫結為函式物件的第一個引數

bind2nd:將引數繫結為函式物件的第二個引數

not1:對一元函式物件取反

not2:對二元函式物件取反

ptr_fun:將普通函式修飾成函式物件

mem_fun:修飾成員函式

mem_fun_ref:修飾成員函式

1、繫結介面卡:bind1st、bind2nd

bind1st和bind2nd函式把一個二元函式物件繫結成為一個一元函式物件。但是由於二元函式物件接受兩個引數,在繫結成為一元函式物件時需要將原來兩個引數中的一個繫結下來。也即通過繫結二元函式物件的一個引數使之成為一元函式物件的。bind1st是繫結第一個引數,bind2nd則是繫結第二個引數。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;

struct MyPrint:public binary_function<int,int,void>
{
    void operator()(int v, int val) const
    {
        cout << v + val << " ";
        cout << "v:" << v << " val:" << val << endl;
        
    }
};
//仿函式介面卡 bind1st bind2nd  繫結介面卡
void test01()
{
    vector<int> v;
    for (int i = 0;i < 10;i++)
    {
        v.push_back(i);
    }

    int addNum = 200;
    //繫結介面卡 將一個二元函式物件轉變成一元函式物件
    for_each(v.begin(), v.end(), bind1st(MyPrint(), addNum));
    /*
    200 v:200 val:0
    201 v:200 val:1
    202 v:200 val:2
    203 v:200 val:3
    204 v:200 val:4
    205 v:200 val:5
    206 v:200 val:6
    207 v:200 val:7
    208 v:200 val:8
    209 v:200 val:9
    */
    for_each(v.begin(), v.end(), bind2nd(MyPrint(), addNum));
    /*
    200 v:0 val:200
    201 v:1 val:200
    202 v:2 val:200
    203 v:3 val:200
    204 v:4 val:200
    205 v:5 val:200
    206 v:6 val:200
    207 v:7 val:200
    208 v:8 val:200
    209 v:9 val:200
    */

    //由此可得bind1st與bind2nd的區別:
    //bind1st 將addNum繫結為函式物件的第一個引數;
    //bind2nd 將addNum繫結為函式物件的第二個引數
}

int main(void)
{
    test01();
    return 0;
}

2、取反介面卡:not1和not2

not1是構造一個與謂詞結果相反的一元函式物件,not2是構造一個與謂詞結果相反的二元函式物件。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;

struct MyCompare :public binary_function<int, int, bool>
{
    //由大到小比較
    bool operator()(int v1,int v2) const
    {
        return v1 > v2;
    }
};

struct MyPrint02
{
    void operator()(int v)
    {
        cout << v << " ";

    }
};

struct MyGreater5:public unary_function<int,bool>
{
    //第一個大於5的數
    bool operator()(int v) const
    {
        return v > 5;
    }
};

//仿函式介面卡 not1 not2 取反介面卡
void test02()
{
    vector<int> v;
    for (int i = 9;i > -1;i--)
    {
        v.push_back(i);
    }

    for_each(v.begin(), v.end(), MyPrint02());
    cout << endl;//9 8 7 6 5 4 3 2 1 0
    sort(v.begin(), v.end(), not2(MyCompare()));//由小到大排序
    for_each(v.begin(), v.end(), MyPrint02());//0 1 2 3 4 5 6 7 8 9
    cout << endl;

    //not1 not2 區別
    //如果對一元謂詞取反,用not1;
    //如果對二元謂詞取反,用not2;

    vector<int>::iterator it = find_if(v.begin(), v.end(), not1(MyGreater5()));//第一個小於等於5的值
    if (it == v.end())
    {
        cout << "沒有找到!" << endl;
    }
    else
    {
        cout << *it << endl;//0
    }
}

int main(void)
{
    test02();
    return 0;
}

3、函式物件介面卡:ptr_fun

 

4、成員函式介面卡:mem_fun、mem_fun_ref