C++ 中的bind

轉自:https://blog.csdn.net/weierqiuba/article/details/71155234
javascript

  
  
  
  
  • 1
#include <functional>

前言
函數綁定bind函數用於把某種形式的參數列表與已知的函數進行綁定,造成新的函數。這種更改已有函數調用模式的作法,就叫函數綁定。須要指出:bind就是函數適配器。css

先上實例:java

  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
#include <iostream> #include <functional> using namespace std; using namespace std::placeholders; int main() { auto fun = [](int *array, int n, int num){ for (int i = 0; i < n; i++) { if (array[i] > num) cout << array[i] << ends; } cout << endl; }; int array[] = { 1, 3, 5, 7, 9 }; //_1,_2 是佔位符 auto fun1 = bind(fun, _1, _2, 5); //等價於調用fun(array, sizeof(array) / sizeof(*array), 5); fun1(array, sizeof(array) / sizeof(*array)); cin.get(); return 0; }

運行結果:ios

  
  
  
  
  • 1
7 9

實例很簡單,你們一看就明白。但有必要說明一下:
問題:什麼是適配器?
適配器是一種機制,把已有的東西改吧改吧、限制限制,從而讓它適應新的邏輯。須要指出,容器、迭代器和函數都有適配器。
bind就是一個函數適配器,它接受一個可調用對象,生成一個新的可調用對象來適應原對象的參數列表。
bind使用的通常形式:bash

  
  
  
  
  • 1
auto newfun = bind(fun, arg_list);

其中fun是一函數,arg_list是用逗號隔開的參數列表。調用newfun(),newfun會調用fun(arg_list);markdown

bind的常見用法一
在本例中,fun()的調用須要傳遞三個參數,而用bind()進行綁定後只需兩個參數了,由於第三個參數在綁定時被固定了下來。減小函數參數的調用,這是bind最多見的用法。函數

2._1,_2是佔位符,定義於命名空間placeholders中。_1是newfun的第一個參數,_2是newfun的第二個參數,以此類推。post

bind的常見用法二
bind的另外一個常見的用法是更改參數的調用順序。如ui

  
  
  
  
  • 1
  • 2
int fun(int a, int b); auto newfun = bind(fun, _2, _1);

調用newfun(1, 2);至關於調用fun(2, 1);spa

1.bind函數的基本介紹

bind函數的最根本的做用就是能夠把一個參數較多的函數給封裝成參數較少的函數,所以對於上述find_if函數的問題,咱們能夠自定義一個含倆個參數的函數,而後經過bind函數進行封裝,使之變成含一個參數的新函數(新函數會調用原來的函數),這樣新函數就能夠被find_if函數的第三個參數所使用了

2.bind的基本形式與使用

bind函數定義在頭文件functional中,咱們能夠將bind函數看做一個通用的函數適配器,它的通常形式以下

  
  
  
  
  • 1
auto newFun = bind(oldFun,arg_list);

參數oldFun是須要bind封裝的源函數,newFun是封裝了參數後的old_Fun,arg_list是一個逗號分割的參數列表,對應oldFun的參數,即當咱們調用newFun是,它會調用oldFun而且會把參數列表中的參數傳給oldFun
arg_list中會包含_n的名字,此類名字的參數又名」佔位符」,由於其佔據了newCallable的參數的位置,其中_n中的n表示它佔據了new_Fun函數中的第幾個參數。
函數的基本形式介紹完了,那麼就進入總體,來爲你們展現一個bind函數在解決find_if問題上是如何作的
實例以下

  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
#include<iostream> #include<vector> #include<algorithm> #include<functional> using namespace std; bool check_size(const int x,int sz) { return x > sz; } int main(void) { vector<int> v = { 1,2,3,4,5,6,7,8,9 }; int n = 5; //有bind函數新封裝生成的函數,其內部調用了check_size auto new_check_size = bind(check_size,std::placeholders::_1,n); auto it = find_if(v.begin(),v.end(),new_check_size); cout<<"第一個大於n的數爲:"<<*it<<endl; return 0; }

3.用bind重排源函數的參數順序

用bind重排源函數的參數順序只需將新函數與源函數的參數列表進行跌倒便可

實現代碼以下

//假定源函數以下

  
  
  
  
  • 1
bool oldFun(int a1,int a2);

//使用bind封裝源函數以下

  
  
  
  
  • 1
auto newFun = bind(old_Fun,_2,_1);

4.使用ref給源函數傳遞引用參數

若是咱們想像lambda表達式同樣傳遞引用,那麼就得使用標準庫中的ref函數,與其相似的是cref其生成的引用是const類型的
具體實例以下

  
  
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
#include<iostream> #include<vector> #include<algorithm> #include<functional> using namespace std; bool check_size(const int x,int &sz) { //改變sz的值 sz = 6; return x > sz; } int main(void) { vector<int> v = { 1,2,3,4,5,6,7,8,9 }; int n = 5; //傳遞n的引用 auto new_check_size = bind(check_size,std::placeholders::_1,ref(n)); auto it = find_if(v.begin(),v.end(),new_check_size); cout<<"n的值爲爲:"<<n<<endl; return 0; }
</div>
      <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-e44c3c0e64.css" rel="stylesheet">
              </div>
posted on 2019-06-25 10:23  泰坦妮克號  閱讀( ...)  評論( ... 編輯 收藏
相關文章
相關標籤/搜索