BOOST::bind 如何使用

boost::bind 是标准函数std::bind1st和std::bind2nd的泛型。它支持函数、函数对象、函

数指针和成员函数指针。它可以绑定任何参数到一个具体的值或者函数到预定义好的位置。


-----------------在函数和函数指针中使用-----------------
int f(int a, int b)
{
  return a + b;
}

int g(int a, int b, int c)
{
  return a + b + c;
}

bind(f, 1, 2) 会生成一个不含参数的空运算函数对象并返回 f(1, 2)。
类似的,bind(g, 1, 2, 3)() 则相当于g(1, 2, 3)。
也可以只指定函数的部分参数。例如
bind(f, _1, 5)(x)相当于f(x, 5);这里的_1是一个参数占位符表示第一个提交的参数。
为了与标准函数想比较,也可以用这种方式实现。
std::bind2nd(std::ptr_fun(f), 5) (x); // = f(x, 5);
当然也可以绑定第一个参数。例如 std::bind1st(Std::ptr_fun(f), 5)(x); // = f(5, x);

bind还可以处理多于两个参数的函数
bind(f, _1, _2, _3)(x, y, z);

参数的传递方式:值传递和引用传递
int i = 5;
bind(f, i, _1);
i的值拷贝会存储在函数对象中。但是如果使用boost::ref或者boost::cref就可以让函数对

象存储一个对象的而引用或者常引用而不是拷贝。


-----------------在函数对象中使用-----------------
bind的使用不仅限于函数,它还支持函数对象。
通常情况下(在result_type没有被指定的情况下),operator()必须显示的设置返回值类型。

struct F
{
    int operator()(int a, int b) { return a - b; }
    bool operator()(long a, long b) { return a == b; }
};
F f;

int x = 1;

bind<int>(f, _1, _1)(x);

注意bind后面加的<int>,这里就表示函数对象的返回值类型。如果有些编译器不支持这种方

式,可以这样来替代。
bind(boost::type<int>(), f, _1, _1)(x);但这只是提供了一种变通方案,并不是接口的一

部分。

在特殊情况下,也就是result_type被指定的情况下,这个显示的返回类型就可以省去。例如

下面的bind后面就没有返回值类型。
struct F2
{
    int s;

    typedef void result_type;
    void operator()( int x ) { s += x; }
};

F2 f2 = { 0 };
int a[] = { 1, 2, 3 };

std::for_each( a, a+3, bind( ref(f2), _1 ) );

assert( f2.s == 6 );


-----------------在成员函数中使用-----------------
成员函数和成员变量的指针不是函数对象,因为它们不支持operator()。为了方便考虑,

bind接收成员指针作为它第一个参数,行为就像boost:mem_fn用来把成员指针转换成一个函

数对象。也就是说表达式bind(&X::f, args)
就等于bind<R>(mem_fn(&X::f),args) // R表示X::f的返回类型或者数据类型。

而mem_fn函数可以通过接收一个指针、引用或者智能指针来创建一个函数对象。
struct X
{
    bool f(int a);
};

X x;

shared_ptr<X> p(new X);

int i = 5;

bind(&X::f, ref(x), _1)(i);        // x.f(i)
bind(&X::f, &x, _1)(i);            //(&x)->f(i)
bind(&X::f, x, _1)(i);            // (internal copy of x).f(i)
bind(&X::f, p, _1)(i);            // (internal copy of p)->f(i)

最后两个例子生成自我包含的函数对象。bind(&X::f, x, _1)存储一个X的拷贝。bind

(&X::f, p, _1)存储一个p的拷贝,因为p是一个boost::shared_ptr,函数对象保留了一个它

的实例X并且即使p超过了作用域或者被reset()都将可用。


-----------------使用嵌套bind组成函数-----------------
bind(f, bind(g, _1)) (x)     // f(g(x))
内层的bind表达式会比外层的bind先被处理;处理的结果会提交到当外部bind被处理的时候的

位置。在这里bind(g, _1)(x)会被最先处理,产生g(x),并且绑定bind(f,g(X))(X)生成最后

的f(g(X))。

当函数对象的是由参数本身或是占位符指定时,以下将不能得到预期的效果
typedef void (*pf)(int);

std::vector<pf> v;
std::for_each(v.begin(), v.end(), bind(_1, 5));

在此我们可以通过使用apply来指定它的第一个参数,作为函数对象。apply在头文件

boost/bind/apply.hpp中定义。所以我们可以这样修改代码。
std::for_each(v.begin(), v.end(), bind(apply<void>(), _1, 5));

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值