bind包装器——C++新特性(三)

🎖  博主的CSDN主页Ryan.Alaskan Malamute
📜 博主的代码仓库主页 [ Gitee ]:@ryanala      [GitHub]: Ryan-Ala

bind

  bind也是一种函数包装器,也叫做适配器。它可以接受一个可调用对象,生成一个新的可调用对象来 “ 适应 ” 原对象的参数列表,C++中的bind本质是一个函数模板

  std::bind 函数定义在头文件 functional 中,是一个函数模板,它也有点像上面的包装器(适配器),接受一个可调用对象(函数/函数名、仿函数对象、lambda 表达式),然后生成一个新的可调用对象来“适应”原对象的参数列表。一般而言,我们用它可以把一个原本接收 N 个参数的可调用对象 Func,通过绑定一些参数,返回一个接收 M 个(通常 M <= N)参数的新函数。另外,使用 std::bind 模板还可以修改参数的传参顺序。

  具体说的话,bind 可以去给可调用对象(通常是静态成员函数)参数列表中的参数指定缺省值,或者更改形参的接收顺序,然后生成一个新的可调用对象来“适应”原对象的参数列表。

bind函数模板的原型

头文件#include<functional>

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);

模板参数说明:

  • fn:可调用对象。
  • args...:要绑定的参数列表:值或占位符。

bind 包装器的用途

  1. 可以调整参数的顺序

    int sub(int a,int b) {  return a-b; }
    int main()
    {
    	function<int(int,int)> f1 = Sub;
    	cout<<f1(10,5)<<endl;
    	//计算得出结果 5
    	using namespace std::placeholders;
    	function<int(int,int)> f2 = bind(Sub,placeholders::_2,placeholders::_1);
    	cout<<f2(10,5)<<endl;
    	//计算的得出结果-5
        //将Sub函数给bind包装器后,可以改变参数的顺序,但是需要用到 placeholders::_2 
        // 此时对应函数在调用时 第二个参数放到第一位置, 
    }
    
  2. 调整参数个数

    //调整参数个数
    using namespace std::placeholders;
    function<int(int,int)> f2 = bind(Sub,20,placeholders::_1);
    cout<<f2(5)<<endl;           //这里Sub函数的第一个操作数就为20,不变了
    //可以使有些参数写死
    
    
    using namespace std::placeholders;
     
    int main(void)
    {
    	void confun(int a, int b, int c);
    	auto con = bind(confun, 3, _2, _1);  //第一个参数绑定指定的函数,后面的参数为绑定函数的参数列表
    	con(5,4);  //之后可以这样调用原函数,且有些参数在绑定时给死
    }
    void confun(int a,int b,int c)
    {
    	cout << "a=" << a << ends << "b=" << b << ends << "c=" << c << endl;
    }
    

bind包装器的意义

  • 将一个函数的某些参数绑定为固定的值,让我们在调用时可以不用传递某些参数。
  • 可以对函数参数的顺序进行灵活调整。

其他使用示例

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

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

struct MyPair {
  double a,b;
  double multiply() {return a*b;}
};

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

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

  auto fn_half = std::bind (my_divide,_1,2);               // returns x/2
  std::cout << fn_half(10) << '\n';                        // 5

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

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

  MyPair ten_two {10,2};

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

  auto bound_member_data = std::bind (&MyPair::a,ten_two); // returns ten_two.a
  std::cout << bound_member_data() << '\n';                // 10

  return 0;
}
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ryan.Alaskan Malamute

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值