bind用于系結可呼叫 (Callable) 物件(函式物件、指向函式指標、到函式參考、指向成員函式指標或指向資料成員指標)和其引數,回傳值為系結成功后的函式物件
C++11中引入的function機制,其中系結器主要有三種:bind1st、bind2nd、bind(C++11)
函式物件
盡管函式指標被廣泛用于實作函式回呼,但C++還提供了一個重要的實作回呼函式的方法,那就是函式物件,函式物件(也稱“函式符”)是多載了“()”運算子的普通類物件,因此從語法上講,函式物件與普通的函式行為類似,
用函式物件代替函式指標有幾個優點:
首先,因為物件可以在內部修改而不用改動外部介面,因此設計更靈活,更富有彈性,函式物件也具備有存盤先前呼叫結果的資料成員,在使用普通函式時需要將先前呼叫的結果存盤在全程或者本地靜態變數中,但是全程或者本地靜態變數有某些我們不愿意看到的缺陷,
其次,在函式物件中編譯器能實作行內呼叫,從而更進一步增強了性能,這在函式指標中幾乎是不可能實作的,
C++11還提供了limbda運算式來實作函式的靈活呼叫,詳見《C++ Primer Plus》第18章
函式物件實際上是類呼叫operator()()小括號運算子多載,實作像在“呼叫函式”一樣的效果,因此還有個別名叫“仿函式”,函式物件示例代碼如下:
class Print {
public:
void operator()(string &s) { cout << s << endl; }
};
int main() {
string s = "hello world!";
Print print; //定義了一個函式物件print
print(s);
return 0;
}
上面代碼print(s);陳述句,看似像函式呼叫,其實是類物件print呼叫其小括號運算子多載print.operator(string &s),print就是一個函式物件,至此對函式物件就有了基本的認識
為什么需要系結器?在使用STL時經常會遇到STL演算法中需要傳遞某元函式物件,比如在寫sort時,第三個引數決定了我們的排序規則,用來接收一個“比較器”函式物件,該函式物件是一個二元的匿名函式物件,形如greator()或者less(),二元函式物件的意思是,這個函式物件的小括號運算子多載函式接收兩個引數,那么幾元就表示接收幾個引數,
我們知道系統自帶的greater()和less()模板類物件是二元匿名函式物件,但是像泛型演算法find_if第三個引數接收一元函式物件,所以需要通過系結器將其轉換為一元函式物件,可以通過bind1st和bind2nd去系結,顧名思義,前者對二元函式物件的第一個引數進行系結,后者對二元函式物件的第二個引數進行系結,兩個系結器均回傳一元函式物件
sort(vec.begin(), vec.end(), greater<int>()); //從大到小對vector進行排序
find\_if(vec.begin(), vec.end(), bind1st(greater<int>(), 70));
find\_if(vec.begin(), vec.end(), bind2nd(less<int>(), 70));
下面給出bind1st系結程序圖,二元函式物件系結了第一個數為70,變為一元函式物件,傳遞給find_if泛型演算法,此時find_if所實作的功能就是:找出有序降序陣列中第一個小于70的數,所以find_if回傳指向65元素的迭代器

系結器
C++ STL
bind1st 將operator()的第一個形參系結成一個確定的值
bind2nd 將operator()的第二個形參系結成一個確定的值
代碼1
#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>
#include <ctime>
using namespace std;
template<typename Container>
void printerContainer(Container & _container) {
typename Container::iterator it_begin = _container.begin();
typename Container::iterator it_end = _container.end();
while (it_begin != it_end) {
cout << *it_begin <<" " ;
++it_begin;
}
}
int main() {
vector < int> vec;
srand(time(nullptr));
for (int i = 0; i < 20; i++) {
vec.push_back((rand() % 100 + 1));
}
printerContainer<vector < int>>(vec);
vector< int>::iterator it_begin= vec.begin();
vector< int>::iterator it_end = vec.end();
sort(it_begin, it_end);//默認小到大排序
cout << endl;
printerContainer<vector < int>>(vec);
cout << endl;
//greater二元函式物件
sort(it_begin, it_end,greater<int>());//大到小排序
printerContainer<vector < int>>(vec);
cout << endl;
//將70按順序插入容器中,找到第一個小于70的元素
//庫里提供的less,greater都是二元的函式物件
//greater a>b
//less a<b;
//系結器 + 二元函式物件 => 一元函式物件
//bind1st: + greater bool operator()(70, const _Ty& _Right)
//greater
//constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const
//{ // apply operator> to operands
// return (_Left > _Right);
//}
//bind2nd: + less bool operator()(const _Ty& _Left, 70)
vector<int>::iterator it_findValue=https://www.cnblogs.com/erichome/p/find_if(it_begin, it_end, bind1st, int>(greater(), 70));
if (it_findValue != it_end) {
vec.insert(it_findValue, 70);
}
printerContainer>(vec);
cout << endl;
system("pause");
return 0;
}
系結器 + 二元函式物件 => 一元函式物件
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/539281.html
標籤:C++
