[C++] C++11 bind 的用法

Bind

Bind可用于绑定函数、成员函数、函数对象、成员变量,bind函数支持最多10个自定义参数

int f(int a, int b) {
    return a + b;
}
std::bind(f, 5, std::placeholders::_1)(x); // 相当于执行了f(5, x);

在上面这段代码中:

  • std::bind函数返回绑定对象,后面跟的(x)表示传参x并执行;
  • std::placeholders::_1是占位符,表示调用时的第一个参数,这段代码里表示x;
  • 如果代码是std::bind(f, std::placeholders::_2, std::placeholders::_1)(x, y)则表示执行f(y, x)
  • 调用前传入的函数参数会被复制并保存在std::bind返回的对象中,比如之前的std::bind(f, 5, std::placeholders::_1)中的5就被存储在了返回的对象中,所以为了性能上考虑,建议传入的类型为引用或指针,避免结构复制

Bind和类成员函数

此时需要注意的是成员函数绑定的第二个参数必须是类实例:

struct X {
    bool f(int a);
};
X x;
std::shared_ptr<X> p(new X);
int i = 5;
std::bind(&X::f, ref(x), std::placeholders::_1)(i); //相当于执行了x.f(i)
std::bind(&X::f, &x, std::placeholders::_1)(i); // 相当于执行了(&x)->f(i)
std::bind(&X::f, x, std::placeholders::_1)(i); // 复制x,并执行(复制的x).f(i)
std::bind(&X::f, p, std::placeholders::_1)(i); //复制智能指针p,并执行(复制的p)->f(i)

由于第二个参数的类实例的保存方式与参数一致,所以也建议传入类引用或类指针,或者智能指针

bind举例

#include <iostream>
#include <cstdio>
#include <memory>
#include <functional>

class Button {
public:
    std::function<void(int)> onClick;
};

class Player{
public:
    void play(void* sender, int param) {
        printf("Play: %d => %d\n", (int)sender, param);
    }
    void stop(void* sender, int param) {
        printf("Play: %d => %d\n", (int)sender, param);
    }
};

Button playButton, stopButton;
Player thePlayer;

void connect() {
    playButton.onClick = std::Bind(&Player::play, &thePlayer, &playButton, std::placeholders::_1);
    stopButton.onClick = std::Bind(&Player::stop, &thePlayer, &stopButton, std::placeholders::_1);
}

int main() {
    connect();
    playButton.onClick(0);
    return 0;
}

上面这段程序其实就是bind在回调函数中的用法,Button类中有一个回调函数onClick(),需要根据不同的场合实现不同的功能,使用bind函数为playButton绑定了play()函数,而为stopButton绑定了stop()函数,这是bind()函数在回调这方面的一个典型用法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值