function 和 bind

发布时间 2023-08-29 21:26:42作者: zxinlog

bind

1. 介绍

bind 可以改变函数的形态,可以将一个函数改变成另一个函数的样式,但只能减少原函数的参数个数,不能增加。

如此处,int add(int, int), 使用bind可以绑定成一个 f 形式,原来的add的两个参数以10,20填入。bind的第一个参数填函数的地址,在普通函数中,函数名就是函数地址,但如果涉及到类的成员函数,就需要 取成员函数的地址,且,成员函数的第一个参数是 this指针,因此,还需要填入一个对象的地址。 (也可以直接传递对象,值传递。)
    
    也就是说,bind的第一个参数是函数地址,后面的参数是该绑定的函数地址的各个参数。
    
	8 #include <functional>
    9 #include <iostream>
   10 using std::bind;
   11 using std::cout;
   12 using std::endl;
   13 
   14 int add(int a, int b) {
   15     return a + b;
   16 }
   17 
   18 int main(int argc, char *argv[]) {
   19     auto f = bind(&add, 10, 20);
   20     cout << "f() = " << f() << endl;
   21     return 0;
   22 }
~            

2. 占位符

bind可以使用占位符将原函数包装成一个新的可以传参的函数。

int add(int a, int b);
using namespace std::placeholders;  // 使用占位符的前置条件。
auto f = bind(&add, _1, _3);
f(1,2,3);

add真正调用时,传递的参数是 1号位和3号位,也就是 1 和 3.
这里要注意,当占位符填 n 的时候,则调用的参数个数 >= n。(写再多也没用,就取占位符的那几个。

占位符本身代表的是形参的位置。占位符中的数字,代表的是实参的位置。

bind默认是值传递。如果想要引用传递的话,则需要使用 std::cref 或者 std::ref 其实就是 const reference

   13 
   14 void print(int a, int b, int c, int d) {
   15     cout << a << " " << b << " " << c << " " << d << endl;
   16 }
   17 
   18 int main(int argc, char *argv[]) {
   19     int number = 100;
   20     using namespace std::placeholders;
   21     auto f = bind(&print, _1, _2, std::cref(number), number);
   22     number = 3;
   23     f(19, 29);
   24     return 0;
   25 }

3. bind返回值

bind 返回值是function, 暂且当作一个函数的容器。用来填充函数类型的。

函数类型就是函数返回值 + 函数参数。(函数参数:参数类型、参数个数、参数顺序)

auto f = bind(...);
function<int()> = bind(...);

function

function< 函数类型 > 函数类型一般是 int() , int表示返回值类型,()表示参数类型。

  • 类的数据成员可以就地初始化。

  • bind可以绑定到类的数据成员上。

  • bind对象可以地址传递,也可以值传递。(地址传递时,使用前不能销毁该对象。)

1. 回调函数

function 可以用来注册回调函数。如:

using CallBack function<int()>;
CallBack _displayCallBack;

右值引用在作为函数参数的时候,是左值,给function 的指针赋值的时候使用 std::move 将其更改为右值。

也就是说,使用 function 定义一个函数指针,然后 bind 传入一个实参,实现 functionbind 的结合。

此时,不但可以以面向对象的形式完成多态, 还可以以基于对象的形式完成多态。

  • 面向对象:继承 + 虚函数(纯虚函数)
  • 基于对象:std::bind + std::function

基于对象更灵活,面向对象更紧密。