謂詞、內建函式物件、函式物件介面卡
阿新 • • 發佈:2018-12-13
一、謂詞概念
謂詞是指普通函式或過載的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