C++ | std::bind

本文介绍了C++中的std::bind函数,包括其函数原型、参数和返回对象的类型。通过实例展示了如何绑定普通函数、类成员函数、模板函数以及使用lambda表达式。还提供了绑定成员变量和静态成员函数的例子。
摘要由CSDN通过智能技术生成

C++ | std::bind

std::bind函数原型

// 无返回值(1)
template <class Fn, class... Args>  /* unspecified */ bind (Fn&& fn, Args&&... args);
// 有返回值(2)
template <class Ret, class Fn, class... Args>  /* unspecified */ bind (Fn&& fn, Args&&... args);

bind函数参数

fn 为绑定的函数对象,比如函数对象、函数指针、函数引用、成员函数或者数据成员函数。

args 为函数的入参列表,使用命名空间占位符std::placeholders::_1(第1个参数),std::placeholders::_2(第2个参数)等标志参数。

每个参数可以绑定到一个值或者是一个占位符:

  • 如果绑定到一个值,调用返回的函数对象将始终使用该值作为参数。
  • 如果是占位符,则调用返回的函数对象会将传递给调用的参数转发给调用(其顺序号由占位符指定的参数)。

调用返回的对象返回与 fn 相同的类型,除非将特定的返回类型指定为 Ret (2)(请注意,Ret 是唯一不能通过传递给此函数的参数隐式推导的模板参数)。

返回对象的类型:

返回一个函数对象,它的返回值与 fn 相同的结果,其参数也绑定到 args…(或转发,用于占位符)。
对如果f是指向类的成员函数,则返回函数第一个参数应该是该类的成员、或者成员对象的引用、或者是成员对象的指针。

实战

1.普通函数/类成员函数/类成员变量

#include <functional>  // std::bind
#include <iostream>    // std::cout

// a function: (also works with function object: std::divides<double>
// randy_divide;)
double randy_divide(double x, double y) { return x / y; }

struct RandyPair {
  double randy, sesame;
  double multiply() { return randy * sesame; }
  static double Add(double lhs, double rhs) {
    return lhs + rhs;
  }
};

int main() {
  using namespace std::placeholders;  // adds visibility of _1, _2, _3,...

  // binding functions:
  auto fn_five = std::bind(randy_divide, 10, 2);  // returns 10/2
  std::cout << fn_five() << '\n';                 // 5

  auto fn_half = std::bind(randy_divide, _1, 2);  // returns x/2
  std::cout << fn_half(22) << '\n';               // 11

  auto fn_invert = std::bind(randy_divide, _2, _1);  // returns y/x
  std::cout << fn_invert(10, 2) << '\n';             // 0.2

  auto fn_rounding = std::bind<int>(randy_divide, _1, _2);  // returns int(x/y)
  std::cout << fn_rounding(9, 3) << '\n';                   // 3

  RandyPair three_eleven{3, 11};

  // binding members:
  auto bound_member_fn =
      std::bind(&RandyPair::multiply, _1);             // returns x.multiply()
  std::cout << bound_member_fn(three_eleven) << '\n';  // 33

  auto bound_member_data =
      std::bind(&RandyPair::randy, three_eleven);  // returns ten_two.a
  std::cout << bound_member_data() << '\n';        // 3
    
   // function pointer
   RandyPair *pRandyPairPtr = new RandyPair();
  pRandyPairPtr->randy = 3.0;
  pRandyPairPtr->sesame = 8.0;
  auto bindFuncPtr = std::bind(&RandyPair::multiply, pRandyPairPtr);
  std::cout << "bindFuncPtr(): " << bindFuncPtr() << '\n'; 

   auto bindClassStaticFunc = std::bind(&RandyPair::Add, _1, _2);
  std::cout << "bindClassStaticFunc(2, 13): " << bindClassStaticFunc(2, 13) << '\n'; 
    
  return 0;
}

结果:

5
11
0.2
3
33
3
bindFuncPtr(): 24
bindClassStaticFunc(2, 13): 15

2.模板函数

#include <functional>  // std::bind
#include <iostream>    // std::cout

template <class T>
void TemplateBindFunc(T lhs, T rhs)
{
    std::cout << "模板函数被调用, lhs = " << lhs << ", rhs = " << rhs << std::endl;
}


int main() {
  using namespace std::placeholders;  // adds visibility of _1, _2, _3,...

  auto templateFunc = std::bind(&TemplateBindFunc<int>, _1, _2);
  templateFunc(2, 13);
  return 0;
}

结果:

模板函数被调用, lhs = 2, rhs = 13

3.lambda表达式

#include <functional>  // std::bind
#include <iostream>    // std::cout

int main() {
  auto lamdaFunc = std::bind(
      [](int randy, int sesame "") {
        std::cout << "lambda表达式, randy = " << randy << ", sesame = " << sesame << std::endl;
      },
      std::placeholders::_1, std::placeholders::_2);
  lamdaFunc(1, 22);
  
  return 0;
}

结果:

lambda表达式, randy = 1, sesame = 22

Reference


欢迎关注公众号【三戒纪元】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值