VC驿站

 找回密码
 加入驿站

QQ登录

只需一步,快速开始

搜索
查看: 1429|回复: 3

[交流] boost 库 bind自己动手实现用于连接原理

[复制链接]
14_avatar_middle
在线会员 发表于 2016-9-4 19:57:52 | 显示全部楼层 |阅读模式
本帖最后由 lin19900801 于 2016-9-4 20:07 编辑

boost::bind 是标准函数 std::bind1st 和 std::bind2nd 的泛化。它支持任意的函数对象,函数,函数指针,和成员函数指针,它还能将任何参数绑定为一个特定的值,或者将输入的参数发送到任意的位置。
具体介绍内容官网:http://www.boost.org/doc/libs/1_53_0/libs/bind/bind.html (英文)  和  我上次分享出来的中文翻译文档( https://www.cctry.com/thread-266663-1-1.html )有详细介绍,例子可以百度找找。先举一个使用的简单例子:
#include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>

class test1
{
public:
  test1() {}
  test1(const test1& p) {}
  ~test1() {}
  void do_something(int& i, int& j)
  {
    i = 9;
    j = 11;
  }
};
int main()
{
  test1 t1;
  int x = 0, y = 0;
  boost::bind(&test1::do_something,  t1, boost::lambda::_1, boost::lambda::_2)(x, y);  //还有种方法是混合function库使用,下文会介绍
  return 0;
}

本文这次目的是自己实现一个类似bind库思路的简化版本,先贴出学习的原文链接,http://www.tqcto.com/article/software/9852.html  ,原文代码就不贴出来了,我自己为了理解原理,去掉了代码中的模板实现,只用c++重复一遍 便于理解bind的实现思路,代码如下:
#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
namespace
{
class placeholder {};
placeholder _1;
}

class Test
{
public:
  Test() {}
  Test(const Test& p) {}
  ~Test() {}
  void do_stuff(const std::vector<int>& v)
  {
    std::vector<int>::const_iterator it = v.begin();
    for (; it != v.end(); ++it) {
      std::cout << *it << std::endl;
    }
  }
};

class simple_bind_t
{
  typedef void(Test::*fn)(const std::vector<int>&);
  fn fn_;
  Test t_;
public:
  simple_bind_t(fn f, const Test& t): fn_(f), t_(t)
  {
    int i = 0;
  }
  ~simple_bind_t()
  {
    int i = 0;
  }

  void operator()(const std::vector<int>& a)
  {
    return (t_.*fn_)(a);
  }
};

simple_bind_t simple_bind(void(Test::*fn)(const std::vector<int>&),
                          const Test& t, const placeholder&)
{
  return simple_bind_t(fn, t);
}

int main()
{
  Test t;
  std::vector<int> vec;
  vec.push_back(42);
  simple_bind(&Test::do_stuff, t, _1)(vec);
  return 0;
}
运行连接:http://ideone.com/HXe5E4
boost中的bind 主要思路是保存传递进来的函数地址和class对象t,在调用的地方调用重载的()函数 ,
若使用boost库function函数,可以把 这行 simple_bind(&Test::do_stuff, t, _1)(vec); 替换成如下方式

boost::function<void(const std::vector<int>&)> fun(simple_bind(&Test::do_stuff, t, _1);
// ... do something
fun(vec);

代码有任何错误请留言指出,不胜感激




上一篇:自己實現的 內存池
下一篇:JS正确的跨域方法
74_avatar_middle
在线会员 发表于 2016-9-5 09:13:31 | 显示全部楼层
boost::bind 中的示例 可能錯誤的
  1. boost::bind(&test1::do_something,  t1, boost::lambda::_1, boost::lambda::_2)(x, y);
复制代码

在bind class成員函數的時候 需要傳遞 實例的 指針 否則 boost 會創建一個 副本(copy 構造) 之後調用的 是副本的 方法
其次 _1 _2 ...等參數 不需要 寫出boost::lambda 也可以
  1. boost::bind(&test1::do_something,  &t1, _1, _2)(x, y);
复制代码

评分

参与人数 1威望 +2 驿站币 +2 热心值 +2 收起 理由
51_avatar_small Syc + 2 + 2 + 2

查看全部评分

14_avatar_middle
ico_lz  楼主| 发表于 2016-9-14 09:49:33 | 显示全部楼层
感谢zuiwuchang 指出问题,收货颇多。 关于问题做点解说,如下代码是会调度 test1的 拷贝构造函数,不过 boost bind实现同样如此,
boost bind对于类对象的值传递方式会调度不止一次
  1. boost::bind(&test1::do_something,  t1, boost::lambda::_1, boost::lambda::_2)(x, y);
复制代码


2、关于参数的问题,若用  boost::lambda::_1 则有限制,最多只能放3个参数,boost::lambda::_1、boost::lambda::_2、boost::lambda::_3,
因为boost::lambda 之定义了这么三个,
而boost bind可容纳的参数最多可以放9个之多!(其中一个是类对象,其余8个用来放置参数),列子见如下代码
  1. #include <iostream>
  2. #include <boost/function.hpp>
  3. #include <boost/bind.hpp>
  4. #include <boost/lambda/lambda.hpp>

  5. class test1
  6. {
  7. public:
  8.   test1() {}
  9.   test1(const test1& p) {} // 拷贝构造
  10.   ~test1() {}
  11.   void do_something(int& x_ , int& y_ , int& z_ , int& f_ , int& g_ , int& h_ ,
  12.                     int& i_ , int& j_)
  13.   {
  14.     x_ = 7;
  15.     y_ = 7;
  16.     z_ = 7;
  17.     f_ = 7;
  18.     g_ = 7;
  19.     h_ = 7;
  20.     i_ = 7;
  21.     j_ = 7;
  22.   }
  23. };
  24. int main()
  25. {
  26.   test1 t1;
  27.   int x = 0, y = 0, z = 0, f = 0, g = 0, h = 0, i = 0 , j = 0 , k = 0;
  28.   // bind中第二个参数 若是指针,则在内部不会调用对应的拷贝构造函数;否则要调用多次拷贝构造函数
  29.   //boost::bind(&test1::do_something, /*t1*/&t1, boost::lambda::_1, boost::lambda::_2)(x, y);
  30.   boost::bind(&test1::do_something, &t1,
  31.               _1, _2, _3, _4, _5, _6, _7, _8)(x , y , z , f , g , h , i , j);
  32.   return 0;
  33. }
复制代码


不吝赐教boost 库 bind自己动手实现用于连接原理
65_avatar_middle
在线会员 发表于 2017-9-19 10:30:45 | 显示全部楼层
std::bind就好boost 库 bind自己动手实现用于连接原理
您需要登录后才可以回帖 登录 | 加入驿站 qq_login

本版积分规则

关闭

站长提醒上一条 /2 下一条

QQ|小黑屋|手机版|VC驿站 ( 辽ICP备09019393号tongdun|网站地图wx_jqr

GMT+8, 2019-7-24 02:37

Powered by Discuz! X3.4

© 2009-2019 cctry.com

快速回复 返回顶部 返回列表