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  泰坦妮克号  阅读( ...)  评论( ... 编辑 收藏
相关文章
相关标签/搜索