C++11 std::function与std::bind

std::function与std::bind

 

std::function

std::function 是一个可调用对象包装器,是一个类模板,可以容纳除了类成员函数指针之外的所有可调用对象,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟它们的执行。

例如

// 普通函数
int add(int a, int b){return a+b;} 

// lambda表达式
auto mod = [](int a, int b){ return a % b;}

// 函数对象类
struct divide{
    int operator()(int denominator, int divisor){
        return denominator/divisor;
    }
};


std::function<int(int ,int)>  a = add; 
std::function<int(int ,int)>  b = mod ; 
std::function<int(int ,int)>  c = divide(); 

 

 std::function 对象最大的用处就是在实现函数回调,使用者需要注意,它不能被用来检查相等或者不相等,但是可以与 NULL 或者 nullptr 进行比较。

 

std::bind

可将std::bind函数看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来“适应”原对象的参数列表。

std::bind将可调用对象与其参数一起进行绑定,绑定后的结果可以使用std::function保存。std::bind主要有以下两个作用:

  • 将可调用对象和其参数绑定成一个仿函数;
  • 只绑定部分参数,减少可调用对象传入的参数。


绑定普通函数

double my_divide(double x, double y) {return x/y;}
auto fn_half = std::bind (my_divide, std::placeholders::_1, 2);  
std::cout << fn_half(10) << std::endl;     // my_divide(10, 2)

其中,std::placeholders::_1 为占位符,是绑定后的函数需要传入的参数。

普通函数做实参时,会隐式转换成函数指针。因此std::bind (my_divide, _1, 2)等价于std::bind (&my_divide, _1, 2);

 

绑定类的成员函数

class Bar {
public:
  void fun1(int x) {
    std::cout << "Bar::fun1(int) called with value: " << x << std::endl;
  }

  static void func2(string y) {
    std::cout << "Bar::fun2(int) called with value: " << y << std::endl;
  }
};

int main() {
  Bar obj;

  // 使用 std::function 绑定成员函数
  std::function<void(int)> func =
      std::bind(&Bar::fun1, &obj, std::placeholders::_1);

  // 调用绑定的成员函数
  func(10); // 输出: Member function called with value: 10

  // 或者使用 lambda 表达式
  std::function<void(int)> lambdaFunc = [&obj](int x) { obj.fun1(x); };

  // 调用 lambda
  lambdaFunc(20); // 输出: Member function called with value: 20

  // 绑定 static 成员函数
  std::function<void(string)> func2 =
      std::bind(&Bar::func2, std::placeholders::_1);
  func2("hello world");

  return 0;
}

提供了两种方式:

  1. 使用 bind 函数;
  2. 使用  lambda 表达式;
 
 

绑定一个引用参数

class Bar {
public:
  void fun1(int &x) {
    x += 10;
    std::cout << "Bar::fun1(int) called with value: " << x << std::endl;
  }
};

int main() {
  Bar obj;
  int value = 10;

  // 使用 std::function 绑定成员函数
  std::function<void(int)> func = std::bind(&Bar::fun1, &obj, std::ref(value));

  // 调用绑定的成员函数
  func(10); // 输出: Member function called with value: 20

  return 0;
}

使用  std::ref(value) 函数 来绑定 value 的引用,这样在调用 func 时,value 的值会被更新。

 

 

posted @ 2024-12-03 10:30  如果的事  阅读(14)  评论(0编辑  收藏  举报