【C++】函数绑定(std::bind)


std::bind 是 C++ 标准库中用于生成新的可调用对象的工具,允许绑定函数参数、调整参数顺序或部分绑定参数。

基本用法

  1. 头文件

    #include <functional>
    using namespace std::placeholders; // 用于占位符 _1, _2 等
    
  2. 绑定普通函数

    void print(int a, int b) {
        std::cout << a << " " << b << std::endl;
    }
    
    // 绑定第二个参数为 100,新函数接受一个参数
    auto print_100 = std::bind(print, _1, 100);
    print_100(50); // 输出:50 100
    
  3. 调整参数顺序

    auto swap_print = std::bind(print, _2, _1);
    swap_print(10, 20); // 输出:20 10
    

绑定成员函数

需提供对象实例作为第一个参数:

class Foo {
public:
    void bar(int a) { std::cout << "Foo::bar " << a << std::endl; }
};

Foo foo;
auto bound_bar = std::bind(&Foo::bar, &foo, _1);
bound_bar(42); // 输出:Foo::bar 42

参数传递方式

  • 按值传递(默认):

    int x = 5;
    auto f = std::bind(print, x, _1);
    x = 10;
    f(20); // 输出:5 20(绑定时的值)
    
  • 按引用传递(使用 std::ref):

    void increment(int &x, int delta) { x += delta; }
    
    int num = 10;
    auto inc = std::bind(increment, std::ref(num), _1);
    inc(5); // num 变为 15
    

绑定函数对象

struct Adder {
    int operator()(int a, int b) { return a + b; }
};

Adder adder;
auto add_5 = std::bind(adder, _1, 5);
std::cout << add_5(10); // 输出:15

处理重载函数

需显式指定函数类型:

void func(int);
void func(double);

auto f = std::bind(static_cast<void(*)(int)>(func), _1);
f(10); // 调用 int 版本

注意事项

  • 生命周期管理:绑定对象指针时,确保对象存活。
  • 占位符顺序_1 对应调用时的第一个参数,依此类推。
  • 返回值类型:使用 autostd::function 接收返回的可调用对象。

对比 Lambda 表达式

Lambda 通常更直观,但 std::bind 在复杂参数调整时可能更简洁:

// 使用 Lambda
auto print_100_lambda = [](int a) { print(a, 100); };
print_100_lambda(50); // 输出:50 100

// 使用 std::bind
auto print_100_bind = std::bind(print, _1, 100);

总结

  • 适用场景:部分参数绑定、参数顺序调整、成员函数绑定。
  • 优先选择 Lambda:在可读性和灵活性要求高时推荐使用 Lambda。
  • 谨慎使用引用:避免悬垂引用,用 std::ref 显式传递。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

晴雨日记

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

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

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

打赏作者

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

抵扣说明:

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

余额充值